Expressible
Utility library, part of the panda-lang SDK, dedicated for functional codebases that require enhanced response handling. Express yourself with inspired by Rust, Kotlin and Vavr wrappers, to provide better API using this tiny library.
Supported wrappers (in panda.std.*
package):
Result<Value, Error>
- solve error handling gracfullyOption<Value>
- enhanced alternative to standard `OptionalLazy<Value>
- lazy values & runnersCompletable<Value>
withPublisher & Subscriber
pattern - synchronized alternative toCompletableFuture<Value>
- Simple reactive containers -
Reference<V>
,MutableReference<V>
,Computed
Mono<A>
,Pair<A, B>
,Triple<A, B, C>
,Quad<A, B, C, D>
- generic wrappers for set of values- Throwing functions, runnables, suppliers and consumers - set of functional interfaces with support for exception signatures
- Tri and Quad consumers, functions and predicates - additional functional interfaces
PandaStream<Value>
-Stream<Value>
wrapper with support for features provided byexpresible
library
repositories {
maven { url 'https://repo.panda-lang.org/releases' }
}
dependencies {
implementation("org.panda-lang:expressible:1.1.9") // Core library
implementation("org.panda-lang:expressible-kt:1.1.9") // Kotlin extensions
implementation("org.panda-lang:expressible-kt-coroutines:1.1.9") // Kotlin coroutines extensions
testImplementation("org.panda-lang:expressible-junit:1.1.9") // JUnit extensions
}
Examples
Suggested snippets show only a small use-cases for the available api. You're not forced to use this library this way, so you may need to find your style in expressing your thoughts. Adopting functional approach requires time and to simplify this process it's easier to slowly introduce new elements based on simple concepts.
Result
Rather than using Exception
based error handling, return meaningful errors and interact with api responses gracefully. Following functional programming patterns make sure your methods don't contain side effects and unexpected exit points.
class UserFacade {
// You can start adoption in a regular, non-functional codebases
fun createUser(username: String): Result<User, String> {
if (userRepository.findUserByName(username).isPresent()) {
return error("User $username already exists")
}
return ok(userRepository.createUser(username))
}
}
class UserEndpoint {
// You can also use fully functional approach
fun createUser(request: HttpRequest, response: HttpResponse) =
userFacade.createUsername(request.param("username"))
.peek { user -> response.respondWithJsonDto(user) }
.onError { error -> ErrorReposne(BAD_REQUEST, error) }
}
internal class UserFacadeTest : UserSpec {
// JUnit support
@Test
fun `should create user with a valid username` () {
// given: a valid username
val username = 'onlypanda'
// when: user is created with the following name
val user = userFacade.createUser(username)
// then: user has been created
assertOk(username, user.map(User::getUsername))
}
}
Option
Similar usage to Optional<Value>
type provided by Java:
Option<String> withValue = Option.of("Value");
Option<String> empty = Option.empty();
Lazy
Lazy<String> completed = new Lazy<>("Value");
Lazy<String> lazy = new Lazy<>(() -> "Value");
Lazy<Void> initialize = Lazy.ofRunnable(() -> "Called just once);
String value = completed.get();
Completable
Completable<String> completable = Completable.create();
completable
.thenApply(value -> parseBoolean(value))
.then(value -> System.out.println(value));
completable.complete("true");
Reactive
Reference<Integer> a = reference(1);
MutableReference<Integer> b = mutableReference(2);
Computed<Integer> result = computed(dependencies(a, b), () -> a.get() + b.get());
result.subscribe(value -> System.out.println(value));
b.update(3); // prints "4"
Panda Stream
PandaStream<String> empty = PandaStream.empty();
PandaStream<String> standard = PandaStream.of(new ArrayList<>().stream());
Used by
- Panda Organization (Panda, Hub, Light)
- Reposilite
- Libraries like CDN, Dependency-Injector
- FunnyGuilds Organization (FunnyGuilds, FunnyCommands)
- Private projects and API consumers of the given libraries