Skip to content

Commit

Permalink
context: add docs and examples to #[operator]
Browse files Browse the repository at this point in the history
  • Loading branch information
Nouzan committed Oct 5, 2023
1 parent 792273e commit da859e5
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/indicator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ pub mod prelude {
#[cfg(feature = "context")]
pub use crate::context::{
extractor::{Data, Env, In, Prev},
input,
layer::{layer_fn, stack::id_layer, Layer, LayerExt},
output, output_with, ContextOperator, ContextOperatorExt, Value, ValueRef,
};
Expand Down
4 changes: 4 additions & 0 deletions crates/indicator_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ proc-macro2 = "1.0.67"
quote = "1.0.33"
syn = { version = "2.0.37", features = ["full"] }
convert_case = "0.6.0"

[dev-dependencies]
indicator = { path = "../indicator", features = ["context"] }
num = "0.4.1"
60 changes: 60 additions & 0 deletions crates/indicator_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,66 @@ fn indicator() -> TokenStream2 {
}

/// Create a `RefOperator` from a function.
///
/// ## Note
/// - When using with the `generate_out` flag, the output type will be converted to the same
/// as `generate_out_with_data`, i.e. `(OutTy, Option<DataTy>)` where `DataTy = ()`
/// is this case. So that it can be used in `insert` method (but not the `insert_env` method).
/// - But when using with the `generate_data` flag, the output type is kept as `Option<DataTy>`,
/// so that it can be used in `insert_data` method.
///
/// ## Example
/// The following example is a basic usage of `#[operator]` attribute.
/// We use `#[operator]` to create a `RefOperator` that just add two to the input.
/// ```rust
/// use indicator::prelude::*;
/// use num::Num;
///
/// struct AddTwo<T>(T);
///
/// /// An operator that just add two to the input.
/// #[operator(input = T)]
/// fn add_two<T>(In(value): In<&T>) -> AddTwo<T>
/// where
/// T: Num + Clone,
/// T: Send + Sync + 'static,
/// {
/// let two = T::one() + T::one();
/// AddTwo(value.clone() + two)
/// }
///
/// let op = input::<i32>().insert_env(add_two).finish();
/// ```
///
/// We notice that the above example requires us to define a struct `AddTwo` to wrap the output.
/// The same operator can also be created with the following code but in a more generic way.
/// ```rust
/// use indicator::prelude::*;
/// use num::Num;
///
/// /// An operator that just add two to the input.
/// #[operator(input = I, generate_out)]
/// fn add_two<T>(#[input] value: &T) -> T
/// where
/// T: Num + Clone,
/// {
/// let two = T::one() + T::one();
/// value.clone() + two
/// }
///
/// let op = input::<i32>().insert(add_two::<_, _, i32>).finish();
/// ```
/// Here we use the `#[input]` attribute and the `generate_out` to achieve our goal.
/// - The `#[input]` attribute is used to mark the input parameter.
/// It will replace the `value: &T` parameter with `In(value): In<&I>` in the generated code,
/// and introduce a bound `I: Borrow<T>` so that it can be converted back to `&T` before calling.
/// - The `generate_out` flag in the `#[operator]` attribute is used to generate a generic output type.
/// Like what the `#[input]` attribute does, it will introduce a bound `OutTy: From<T>`
/// (here the `OutTy` is the generated output type) so that the output can be converted from `T`.
///
/// Also note that the operator generated with `generate_out` flag is meant to be used with `insert` method,
/// because the output type is wrapped in a tuple `(OutTy, Option<DataTy>)` where `DataTy = ()` is this case.
/// If you want to costomize the `DataTy`, you can use the `generate_out_with_data` flag instead.
#[proc_macro_attribute]
pub fn operator(args: TokenStream, input: TokenStream) -> TokenStream {
match self::operator::generate_operator(args, input) {
Expand Down

0 comments on commit da859e5

Please sign in to comment.