Expand description
§Stillwater
A Rust library for pragmatic effect composition and validation.
§Philosophy
Stillwater embodies the principle of pure core, imperative shell:
- Still = Pure functions (unchanging, referentially transparent)
- Water = Effects (flowing, performing I/O)
§Effect System
The effect system has been redesigned to be zero-cost by default with opt-in boxing
when type erasure is needed, following the established futures crate pattern.
ⓘ
use stillwater::effect::prelude::*;
// Zero heap allocations - compiler can inline everything
let effect = pure::<_, String, ()>(42)
.map(|x| x + 1)
.and_then(|x| pure(x * 2));
// Use .boxed() when you need type erasure
let effects: Vec<BoxedEffect<i32, String, ()>> = vec![
pure(1).boxed(),
pure(2).map(|x| x * 2).boxed(),
];§Quick Example
use stillwater::Validation;
// Accumulate all validation errors
fn validate_email(email: &str) -> Validation<String, Vec<String>> {
if email.contains('@') {
Validation::success(email.to_string())
} else {
Validation::failure(vec!["Email must contain @".to_string()])
}
}
fn validate_age(age: i32) -> Validation<i32, Vec<String>> {
if age >= 18 {
Validation::success(age)
} else {
Validation::failure(vec!["Must be 18 or older".to_string()])
}
}
// Collect all errors at once
let result = Validation::<(String, i32), Vec<String>>::all((
validate_email("[email protected]"),
validate_age(25),
));
match result {
Validation::Success((email, age)) => {
println!("Valid: {} is {} years old", email, age);
}
Validation::Failure(errors) => {
println!("Errors: {:?}", errors);
}
}For more examples, see the examples directory.
Re-exports§
pub use effect::BoxedEffect;pub use effect::Effect;pub use effect::EffectContext;pub use effect::EffectContextChain;pub use effect::EffectExt;pub use effect::boxed::BoxFuture;pub use effect::boxed::BoxedLocalEffect;pub use effect::constructors::ask;pub use effect::constructors::asks;pub use effect::constructors::fail;pub use effect::constructors::from_async;pub use effect::constructors::from_fn;pub use effect::constructors::from_option;pub use effect::constructors::from_result;pub use effect::constructors::from_validation;pub use effect::constructors::local;pub use effect::constructors::pure;pub use effect::constructors::zip3;pub use effect::constructors::zip4;pub use effect::constructors::zip5;pub use effect::constructors::zip6;pub use effect::constructors::zip7;pub use effect::constructors::zip8;pub use effect::parallel::par2;pub use effect::parallel::par3;pub use effect::parallel::par4;pub use effect::parallel::par_all;pub use effect::parallel::par_all_limit;pub use effect::parallel::par_try_all;pub use effect::parallel::race;pub use effect::combinators::AndThen;pub use effect::combinators::AndThenAuto;pub use effect::combinators::AndThenRef;pub use effect::combinators::Check;pub use effect::combinators::Fail;pub use effect::combinators::FromAsync;pub use effect::combinators::FromFn;pub use effect::combinators::FromResult;pub use effect::combinators::Map;pub use effect::combinators::MapErr;pub use effect::combinators::OrElse;pub use effect::combinators::Pure;pub use effect::combinators::Tap;pub use effect::combinators::With;pub use effect::combinators::Zip;pub use effect::combinators::Zip3;pub use effect::combinators::Zip4;pub use effect::combinators::Zip5;pub use effect::combinators::Zip6;pub use effect::combinators::Zip7;pub use effect::combinators::Zip8;pub use effect::combinators::ZipWith;pub use effect::reader::Ask;pub use effect::reader::Asks;pub use effect::reader::Local;pub use effect::bracket::bracket_simple;Deprecated pub use effect::bracket::acquiring;pub use effect::bracket::bracket;pub use effect::bracket::bracket2;pub use effect::bracket::bracket3;pub use effect::bracket::bracket_full;pub use effect::bracket::bracket_sync;pub use effect::bracket::Acquiring;pub use effect::bracket::Bracket;pub use effect::bracket::Bracket2;pub use effect::bracket::Bracket3;pub use effect::bracket::BracketError;pub use effect::bracket::BracketFull;pub use effect::bracket::BracketSync;pub use effect::bracket::Resource;pub use effect::bracket::ResourceWith;pub use effect::compat::LegacyConstructors;Deprecated pub use effect::compat::LegacyEffect;Deprecated pub use effect::compat::RunStandalone;pub use context::ContextError;pub use io::IO;pub use monoid::Monoid;pub use nonempty::NonEmptyVec;pub use retry::JitterStrategy;pub use retry::RetryEvent;pub use retry::RetryExhausted;pub use retry::RetryPolicy;pub use retry::RetryStrategy;pub use retry::TimeoutError;pub use semigroup::First;pub use semigroup::Intersection;pub use semigroup::Last;pub use semigroup::Semigroup;pub use validation::Validation;pub use either::Either;
Modules§
- context
- Context error handling with error trails
- effect
- Zero-cost Effect trait with opt-in boxing.
- either
- A semantically neutral sum type for representing one of two possible values.
- io
- IO module for creating Effect instances from I/O operations
- monoid
- Monoid trait for types with identity elements
- nonempty
- Non-empty vector type for type-safe collections
- predicate
- Predicate combinators for composable validation logic
- prelude
- Prelude module for convenient imports
- refined
- Refined types for compile-time validation guarantees
- retry
- Retry and resilience patterns for Effect-based computations.
- semigroup
- Semigroup trait for associative operations
- testing
- Testing utilities and helpers for Stillwater
- traverse
- Traverse and sequence utilities for working with collections of effects
- validation
- Validation module for accumulating errors and ensuring data consistency
Macros§
- assert_
failure - Assert that a validation fails.
- assert_
success - Assert that a validation succeeds.
- assert_
validation_ errors - Assert that a validation fails with specific errors.
- par
- Macro for arbitrary parallel execution with tuple return.