diff --git a/README.md b/README.md index 96e40f500..abd3e5d33 100644 --- a/README.md +++ b/README.md @@ -211,8 +211,8 @@ the concepts, the construct reference, the comparisons, and the project pages. T documentation on [docs.rs](https://docs.rs/cgp) is the place to look up an item. > [!NOTE] -> Each crate's `docs.rs` page says what that crate provides and links the reference page for its -> constructs. The per-item documentation is still being filled in, so the website remains the place +> Each crate's `docs.rs` page says what that crate provides, and every public item carries a short +> doc. Each construct's doc links the reference page that explains it. The website remains the place > to start. Contributors and coding agents have a second, deeper source: the diff --git a/crates/core/cgp-base-types/src/lib.rs b/crates/core/cgp-base-types/src/lib.rs index 9fe32fb58..0ab9e45f7 100644 --- a/crates/core/cgp-base-types/src/lib.rs +++ b/crates/core/cgp-base-types/src/lib.rs @@ -2,7 +2,12 @@ //! //! See [`Symbol!`](https://contextgeneric.dev/docs/reference/macros/symbol), [`Cons`](https://contextgeneric.dev/docs/reference/types/cons), [`Nil`](https://contextgeneric.dev/docs/reference/types/nil), [`Chars`](https://contextgeneric.dev/docs/reference/types/chars), [`PathCons`](https://contextgeneric.dev/docs/reference/types/path_cons), [`StaticFormat`](https://contextgeneric.dev/docs/reference/traits/formatting/static_format), and [`ConcatPath`](https://contextgeneric.dev/docs/reference/traits/formatting/concat_path). #![no_std] +#![warn(missing_docs)] +/// Re-exports the type-level primitives that the macros expand to. pub mod macro_prelude; +/// The type-level traits: [`traits::StaticFormat`] and [`traits::ConcatPath`]. pub mod traits; +/// The type-level types: [`types::Symbol`], [`types::Chars`], [`types::Cons`], [`types::Nil`], and +/// [`types::PathCons`]. pub mod types; diff --git a/crates/core/cgp-base-types/src/traits/concat_path.rs b/crates/core/cgp-base-types/src/traits/concat_path.rs index f34f03b1a..d5458ddd2 100644 --- a/crates/core/cgp-base-types/src/traits/concat_path.rs +++ b/crates/core/cgp-base-types/src/traits/concat_path.rs @@ -1,6 +1,11 @@ use crate::types::{Nil, PathCons}; +/// Join two type-level paths, as the generated lookup behind namespaces and open does to append a +/// component's type parameters to its route. +/// +/// See [`ConcatPath`](https://contextgeneric.dev/docs/reference/traits/formatting/concat_path). pub trait ConcatPath { + /// The concatenated path. type Output: ?Sized; } diff --git a/crates/core/cgp-base-types/src/traits/static_format.rs b/crates/core/cgp-base-types/src/traits/static_format.rs index 45d68384b..b6a58d75b 100644 --- a/crates/core/cgp-base-types/src/traits/static_format.rs +++ b/crates/core/cgp-base-types/src/traits/static_format.rs @@ -2,7 +2,12 @@ use core::fmt::{self, Formatter}; use crate::types::{Chars, Nil}; +/// Write a type-level string's characters into a formatter without a value to format; the trait +/// behind Display on Symbol and Chars. +/// +/// See [`StaticFormat`](https://contextgeneric.dev/docs/reference/traits/formatting/static_format). pub trait StaticFormat { + /// Writes the string to the formatter. fn fmt(f: &mut Formatter<'_>) -> Result<(), fmt::Error>; } diff --git a/crates/core/cgp-base-types/src/types/chars.rs b/crates/core/cgp-base-types/src/types/chars.rs index 9e31f7444..e4e17fb9b 100644 --- a/crates/core/cgp-base-types/src/types/chars.rs +++ b/crates/core/cgp-base-types/src/types/chars.rs @@ -3,39 +3,10 @@ use core::marker::PhantomData; use crate::traits::StaticFormat; -/** - The `Chars` type is used to represent _type-level_ list of - `Chars`s, which are equivalent to type-level strings. - - `Chars` is a specialized version of [`Cons`](crate::types::Cons), with the - `Head` type being fixed to a _const-generic_ value of type `Chars`. - Similar to `Cons`, `Chars` is also parameterized by a `Tail` type, which is - expected to be either the next `Chars`, or [`Nil`](crate::types::Nil) to - represent the end of the string. - - We represent type-level strings as list of `Chars`s, because it is currently - not possible to use types like `String` or `&str` as const-generic parameters. - On the other hand, a single `Chars` can be used as a const-generic parameter, - and so we can workaround the limitation by combining a type-level list of - `Chars`s to represent a type-level string. - - `Chars` is most often not used directly, but rather through the `Symbol!` macro, - which accepts a string literal and converts it into a list of `Chars`s. - - ## Example - - Given the following symbol definition: - - ```rust,ignore - type Hello = Symbol!("hello"); - ``` - - The following type would be generated: - - ```rust,ignore - type Hello = Chars<'h', Chars<'e', Chars<'l', Chars<'l', Chars<'o', Nil>>>>>; - ``` -*/ +/// The character list behind Symbol!, which spells a field name out one character at a time so the +/// name can be a type in trait resolution. +/// +/// See [`Chars`](https://contextgeneric.dev/docs/reference/types/chars). #[derive(Eq, PartialEq, Clone, Copy, Default)] pub struct Chars(pub PhantomData); diff --git a/crates/core/cgp-base-types/src/types/cons.rs b/crates/core/cgp-base-types/src/types/cons.rs index 052916706..5bd1b401a 100644 --- a/crates/core/cgp-base-types/src/types/cons.rs +++ b/crates/core/cgp-base-types/src/types/cons.rs @@ -1,23 +1,6 @@ -/** - The `Cons` type is used to represent the head of a _type-level list_, - also known as an _anonymous product type_. - - `Cons` is used together with [`Nil`](crate::types::Nil) to produce a type-level list using - the `Product!` macro. - - ## Example - - Given the following product type definition: - - ```rust,ignore - type MyTypes = Product![u32, String, bool]; - ``` - - The following type would be generated: - - ```rust,ignore - type MyTypes = Cons>>; - ``` -*/ +/// The head-and-tail cell of the type-level product list, which describes a record one field at a +/// time so generic code can walk any struct's fields. +/// +/// See [`Cons`](https://contextgeneric.dev/docs/reference/types/cons). #[derive(Eq, PartialEq, Clone, Default, Debug)] pub struct Cons(pub Head, pub Tail); diff --git a/crates/core/cgp-base-types/src/types/nil.rs b/crates/core/cgp-base-types/src/types/nil.rs index ef5af5228..0e315c26c 100644 --- a/crates/core/cgp-base-types/src/types/nil.rs +++ b/crates/core/cgp-base-types/src/types/nil.rs @@ -1,11 +1,6 @@ -/** - The `Nil` type is used to represent the end of a _type-level list_, - or an empty type-level list. - - `Nil` is commonly used as the `Tail` of a [`Cons`](crate::types::Cons) type, to terminate the list. - When used on its own, it represents an empty type-level list. - - Read more about type-level lists, a.k.a. the product types, in [`Cons`](crate::types::Cons). -*/ +/// The end marker of the product, string, and path lists: an empty, constructible list that is also +/// the shape of a unit struct. +/// +/// See [`Nil`](https://contextgeneric.dev/docs/reference/types/nil). #[derive(Eq, PartialEq, Clone, Default, Debug)] pub struct Nil; diff --git a/crates/core/cgp-base-types/src/types/path.rs b/crates/core/cgp-base-types/src/types/path.rs index 48bc11bf0..ebb823fd1 100644 --- a/crates/core/cgp-base-types/src/types/path.rs +++ b/crates/core/cgp-base-types/src/types/path.rs @@ -1,3 +1,7 @@ use core::marker::PhantomData; +/// The cell of a type-level path, the list of segments that names a route through nested delegation +/// tables so a lookup can reach an entry behind a prefix. +/// +/// See [`PathCons`](https://contextgeneric.dev/docs/reference/types/path_cons). pub struct PathCons(pub PhantomData, pub PhantomData); diff --git a/crates/core/cgp-base-types/src/types/symbol.rs b/crates/core/cgp-base-types/src/types/symbol.rs index 7b88158a0..f15922221 100644 --- a/crates/core/cgp-base-types/src/types/symbol.rs +++ b/crates/core/cgp-base-types/src/types/symbol.rs @@ -1,6 +1,9 @@ use core::fmt::Display; use core::marker::PhantomData; +/// A type-level string, used as the tag that names a struct field in CGP's field-access traits. +/// +/// See [`Symbol!`](https://contextgeneric.dev/docs/reference/macros/symbol). pub struct Symbol(pub PhantomData); use crate::traits::StaticFormat; diff --git a/crates/core/cgp-component/src/lib.rs b/crates/core/cgp-component/src/lib.rs index f29609fed..123b69410 100644 --- a/crates/core/cgp-component/src/lib.rs +++ b/crates/core/cgp-component/src/lib.rs @@ -3,7 +3,9 @@ //! providers. //! //! See [`DelegateComponent`](https://contextgeneric.dev/docs/reference/traits/wiring/delegate_component), [`IsProviderFor`](https://contextgeneric.dev/docs/reference/traits/wiring/is_provider_for), [`CanUseComponent`](https://contextgeneric.dev/docs/reference/traits/wiring/can_use_component), [`UseContext`](https://contextgeneric.dev/docs/reference/providers/use_context), [`UseDefault`](https://contextgeneric.dev/docs/reference/providers/use_default), [`UseDelegate`](https://contextgeneric.dev/docs/reference/providers/use_delegate), and [`RedirectLookup`](https://contextgeneric.dev/docs/reference/providers/redirect_lookup). +#![warn(missing_docs)] +/// Re-exports the component machinery that the macros expand to. pub mod macro_prelude; mod namespaces; diff --git a/crates/core/cgp-component/src/namespaces.rs b/crates/core/cgp-component/src/namespaces.rs index 3daddeb5c..10914e269 100644 --- a/crates/core/cgp-component/src/namespaces.rs +++ b/crates/core/cgp-component/src/namespaces.rs @@ -1,11 +1,30 @@ +/// The namespace trait a context joins with a namespace header, resolving each component's default +/// route; prefix registers components into it. +/// +/// See +/// [`DefaultNamespace`](https://contextgeneric.dev/docs/reference/traits/namespace/default_namespace) +/// . pub trait DefaultNamespace { + /// The provider the namespace delegates to. type Delegate; } +/// The lookup trait for a namespace default keyed on a component and one type, which default_impl +/// registers into and a for loop reads back. +/// +/// See [`DefaultImpls1`](https://contextgeneric.dev/docs/reference/traits/namespace/default_impls1) +/// . pub trait DefaultImpls1 { + /// The provider the default delegates to. type Delegate; } +/// The lookup trait for a namespace default keyed on a component and a pair of types, reachable +/// through default_impl and a for loop. +/// +/// See [`DefaultImpls2`](https://contextgeneric.dev/docs/reference/traits/namespace/default_impls2) +/// . pub trait DefaultImpls2 { + /// The provider the default delegates to. type Delegate; } diff --git a/crates/core/cgp-component/src/providers/redirect_lookup.rs b/crates/core/cgp-component/src/providers/redirect_lookup.rs index dbc117e56..e3ee6c955 100644 --- a/crates/core/cgp-component/src/providers/redirect_lookup.rs +++ b/crates/core/cgp-component/src/providers/redirect_lookup.rs @@ -1,3 +1,7 @@ use core::marker::PhantomData; +/// The generated provider that answers a component by looking a type-level path up in a table, the +/// mechanism behind namespaces and the open statement. +/// +/// See [`RedirectLookup`](https://contextgeneric.dev/docs/reference/providers/redirect_lookup). pub struct RedirectLookup(pub PhantomData<(Key, Components)>); diff --git a/crates/core/cgp-component/src/providers/use_context.rs b/crates/core/cgp-component/src/providers/use_context.rs index dac4b19c6..ff85f67d5 100644 --- a/crates/core/cgp-component/src/providers/use_context.rs +++ b/crates/core/cgp-component/src/providers/use_context.rs @@ -1,48 +1,13 @@ use crate::WithProvider; -/** - The `UseContext` pattern is used to define a trivial implementation of - a provider trait, by forwarding the implementation to the consumer trait - implementation of the context. - - This pattern is the _dual_ of the blanket implementation of a consumer trait, - which forwards the implementation to its provider through the `CgpProvider` trait. - - The main use case for `UseContext` is to be used as a _higher-order provider_ - in the argument to a different provider implementation. This decouples the - dependencies between different CGP traits, and allows non-default providers - to be used within another provider implementation. - - For obvious reasons, `UseContext` should not be used as the delegation target - from the context provider, as it would result in a cyclic dependency error. - - The `UseContext` provider is automatically implemented for all CPG traits that - are generated from `#[cgp_component]`. - - ## Example - - Given the following component definition: - - ```rust,ignore - #[cgp_component(Greeter)] - pub trait CanGreet { - fn greet(&self); - } - ``` - - The following `UseContext` implementation would be generated: - - ```rust,ignore - impl Greeter for UseContext - where - Context: CanGreet, - { - fn greet(context: &Context) { - context.greet() - } - } - ``` -*/ +/// The provider that implements a provider trait by calling the context's own consumer trait, +/// usually as a higher-order provider's default inner provider. +/// +/// See [`UseContext`](https://contextgeneric.dev/docs/reference/providers/use_context). pub struct UseContext; +/// The alias WithProvider``: a named type or getter component answered by the context's +/// own HasType or HasField entry, keyed by the component. +/// +/// See [`WithContext`](https://contextgeneric.dev/docs/reference/providers/with_context). pub type WithContext = WithProvider; diff --git a/crates/core/cgp-component/src/providers/use_default.rs b/crates/core/cgp-component/src/providers/use_default.rs index f6a2e3187..49918c594 100644 --- a/crates/core/cgp-component/src/providers/use_default.rs +++ b/crates/core/cgp-component/src/providers/use_default.rs @@ -1 +1,5 @@ +/// The marker provider for a component whose implementation is the consumer trait's own default +/// method bodies, given meaning by an empty `#[cgp_impl]` block. +/// +/// See [`UseDefault`](https://contextgeneric.dev/docs/reference/providers/use_default). pub struct UseDefault; diff --git a/crates/core/cgp-component/src/providers/use_delegate.rs b/crates/core/cgp-component/src/providers/use_delegate.rs index 5963b4d20..07d17eff6 100644 --- a/crates/core/cgp-component/src/providers/use_delegate.rs +++ b/crates/core/cgp-component/src/providers/use_delegate.rs @@ -1,57 +1,7 @@ use core::marker::PhantomData; -/** - The `UseDelegate` pattern is used as the _default dispatcher_ for CGP - components that contain additional generic parameters in their traits. - - When a provider trait contains additional generic parameters in addition - to the `Context` type, CGP can generate a `UseDelegate` implementation - that uses `Components` as a _type-level lookup table_ to dispatch the - implementation to different providers based on the generic types. - - The implementation of `UseDelegate` follows the same pattern as the - blanket implementation of a provider trait. However, instead of using - the component name type as the key, it uses the specified generic - parameters as the key to lookup the provider through `DelegateComponent`. - - `UseDelegate` is very commonly used to perform ad hoc dispatch of - concrete types to different context-generic providers. This allows the - providers to remain generic, even when they may have implementations - that overlaps on the generic parameters. - - The implementation of `UseDelegate` can be automatically generated through - the `#[derive_delegate]` attribute in `#[cgp_component]`. It is also possible to - implement the dispatcher pattern on types other than `UseDelegate`, especially - when there are multiple generic parameters that could be dispatched differently. - We mainly use `UseDelegate` as the default dispatcher, so that users don't need - to remember the different provider types to be used with each component. - - ## Example - - Given the following component definition: - - ```rust,ignore - #[cgp_component(ErrorRaiser)] - #[derive_delegate(UseDelegate)] - pub trait CanRaiseError: HasErrorType { - fn raise_error(error: SourceError) -> Self::Error; - } - ``` - - The following `UseDelegate` implementation would be generated: - - ```rust,ignore - impl ErrorRaiser - for UseDelegate - where - Context: HasErrorType, - Components: DelegateComponent<(SourceError), Delegate = Delegate>, - Delegate: ErrorRaiser, - { - fn raise_error(error: SourceError) -> Context::Error { - Delegate::raise_error(error) - } - } - ``` -*/ +/// The legacy provider that routes a component to a different inner provider per generic-parameter +/// type through a nested table; open replaces it. +/// +/// See [`UseDelegate`](https://contextgeneric.dev/docs/reference/providers/use_delegate). pub struct UseDelegate(pub PhantomData); diff --git a/crates/core/cgp-component/src/providers/use_fields.rs b/crates/core/cgp-component/src/providers/use_fields.rs index 9e18e0931..155286f60 100644 --- a/crates/core/cgp-component/src/providers/use_fields.rs +++ b/crates/core/cgp-component/src/providers/use_fields.rs @@ -1 +1,5 @@ +/// The provider that implements every method of a getter component by reading the context field +/// named after the method, for any number of methods. +/// +/// See [`UseFields`](https://contextgeneric.dev/docs/reference/providers/use_fields). pub struct UseFields; diff --git a/crates/core/cgp-component/src/providers/with_provider.rs b/crates/core/cgp-component/src/providers/with_provider.rs index 851126c05..fe2c53027 100644 --- a/crates/core/cgp-component/src/providers/with_provider.rs +++ b/crates/core/cgp-component/src/providers/with_provider.rs @@ -1,3 +1,7 @@ use core::marker::PhantomData; +/// The adapter that turns a TypeProvider or FieldGetter into a named component's provider, spelled +/// in wiring through the With… aliases. +/// +/// See [`WithProvider`](https://contextgeneric.dev/docs/reference/providers/with_provider). pub struct WithProvider(pub PhantomData); diff --git a/crates/core/cgp-component/src/traits/can_use_component.rs b/crates/core/cgp-component/src/traits/can_use_component.rs index 15fdee9f6..183291cfa 100644 --- a/crates/core/cgp-component/src/traits/can_use_component.rs +++ b/crates/core/cgp-component/src/traits/can_use_component.rs @@ -1,18 +1,10 @@ use crate::{DelegateComponent, IsProviderFor}; -/** - This is a convenient type alias that is used in the same way as [`IsProviderFor`], - but with the `Self` type being the `Context` type rather than the `Provider` type - that implements the provider trait. - - The `CanUseComponent` trait is automatically implemented for any CGP `Context` type - that implements the `DelegateComponent` trait, and when `Contex::Delegate` - implements `IsProviderFor`. - - This trait is used by `check_components!` to check whether a `Context` implements - a given `Component` through its provider. When there are unsatisfied constraints, - Rust would show the error messages from the `IsProviderFor` implementation. -*/ +/// The check a check_components! entry asserts: the context wires the component, and the provider +/// it chose has every dependency met for that context. +/// +/// See +/// [`CanUseComponent`](https://contextgeneric.dev/docs/reference/traits/wiring/can_use_component) . pub trait CanUseComponent {} impl CanUseComponent for Context diff --git a/crates/core/cgp-component/src/traits/delegate_component.rs b/crates/core/cgp-component/src/traits/delegate_component.rs index 446d2c54f..986f80225 100644 --- a/crates/core/cgp-component/src/traits/delegate_component.rs +++ b/crates/core/cgp-component/src/traits/delegate_component.rs @@ -1,44 +1,10 @@ -/** - This is the core trait used by the `delegate_component!` macro to define a mapping - from `Name` to `Delegate` on the target `Self` type. - - ## `DelegateComponent` as a type-level key-value map - - Essentially, `DelegateComponent` turns the `Self` type into a type-level key-value map, - with `Name` as the key and `Delegate` as the value. The implementation of - `DelegateComponent` serves as "setting" an entry of `Self` at `Name` to `Delegate`. - Then, the inclusion of `DelegateComponent` in a constraint serves as "getting" the - `Delegate` value with the provided `Name` as the key. - - When `Name` type in `DelegateComponent` is a CGP component name type, then the `Self` - type would also automatically implement the corresponding provider trait through the - blanket implementation. - - However, it is also common to use `DelegateComponent` with regular types as the `Name` - key, especially when it is used to define lookup tables for providers such as - `UseDelegate`. In such cases, the `Self` type that implements `DelegateComponent` would - not be used to implement any provider trait. - - ## Examples - - As an example, given the following `delegate_component!` macro invocation: - - ```rust,ignore - delegate_component! { - MyComponent { - GreeterComponent: GreetHello, - } - } - ``` - - would generate the following impl: - - ```rust,ignore - impl DelegateComponent for MyComponent { - type Delegate = GreetHello; - } - ``` -*/ +/// The trait a wiring table is made of: one impl per entry, mapping a key such as a component name +/// to the provider a context chose for it. +/// +/// See +/// [`DelegateComponent`](https://contextgeneric.dev/docs/reference/traits/wiring/delegate_component) +/// . pub trait DelegateComponent { + /// The provider the context delegates the component to. type Delegate; } diff --git a/crates/core/cgp-component/src/traits/is_provider.rs b/crates/core/cgp-component/src/traits/is_provider.rs index b1e0a5e9f..a10613789 100644 --- a/crates/core/cgp-component/src/traits/is_provider.rs +++ b/crates/core/cgp-component/src/traits/is_provider.rs @@ -1,120 +1,5 @@ -/** - The `IsProviderFor` trait is used to propagate the constraints required to - implement the provider trait that corresponds to the `Component` type. - - ## Parameters - - The `IsProviderFor` trait parameters are used as follows: - - - `Component`: The component name type that corresponds to the provider trait. - - `Context`: The `Context` type used in the provider trait. - - `Params`: Any additional generic parameters in the provider trait, with - multiple generic parameters grouped inside a tuple. - - ## `IsProviderFor` as a constraint carrier - - The trait definition for `IsProviderFor` has an empty body that can be trivially - implemented. However, when used with `#[cgp_provider]` or `#[cgp_new_provider]`, - on a provider trait implementation, it would be implemented by the `Provider` type - with the same set of constraints as the provider trait implementation. - - The `IsProviderFor` trait is included as a supertrait of all CGP provider traits - generated from `#[cgp_component]`. This means that when there is any unsatisfied - constraint in the provider trait implementation, it would also result in the - same error shown in the `IsProviderFor` implementation. - - ## Why is this trait necessary? - - The trait is necessary to force the Rust compiler to show any relevant error message - when there are unsatisfied constraints in the provider trait implementation. By default, - Rust would hide the error messages from the provider trait implementation, because there - is also an alternative candidate implementation available, which is the blanket - implementation of the provider trait. - - On the other hand, the `IsProviderFor` trait is explicitly propagated inside - `delegate_components!`, together with `DelegateComponent`. Because of this different - implementation path, we are able to "unhide" the error messages that were hidden away - by Rust. - - ## Example Definition - - Given a CGP trait definition such as: - - ```rust,ignore - #[cgp_component(FooGetterAt)] - pub trait CanGetFooAt { - fn foo_at(&self, _phantom: PhantomData<(I, J)>) -> u64; - } - ``` - - The following provider trait would be generated with the `IsProviderFor` supertrait: - - ```rust,ignore - pub trait FooGetterAt: - IsProviderFor - { - fn foo_at(context: &Context, _phantom: PhantomData<(I, J)>) -> u64; - } - ``` - - ## Example Implementation - - Given a provider trait implementation such as: - - ```rust,ignore - #[cgp_provider(FooGetterAt)] - impl FooGetterAt for GetFooValue - where - Context: HasField, - { - fn foo_at(context: &Context, _phantom: PhantomData<(I, J)>) -> u64 { - context.get_field(PhantomData) - } - } - ``` - - The following implementation for `IsProviderFor` would be generated: - - ```rust,ignore - impl - IsProviderFor - for GetFooValue - where - Context: HasField, - { - } - ``` - - ## Example Delegation - - Given a component delegation such as: - - ```rust,ignore - delegate_component! { - MyAppComponents { - FooGetterAtComponent: GetFooValue, - } - } - ``` - - The following `IsProviderFor` implementation would be generated: - - ```rust,ignore - impl - IsProviderFor - for MyAppComponents - where - GetFooValue: IsProviderFor, - { - } - ``` - - This means that `MyAppComponents` has an explicit implementation of `IsProviderFor` - for all possible `Context` and `Params`, with the `where` constraint propagating - the constraints coming from `GetFooValue` with the same `Context` and `Params`. - - Because of this is an explicit implementation and not a blanket implementation, - Rust would follow the implementation path and surface all unsatisfied constraints - from `GetFooValue`. -*/ +/// The empty marker every provider trait requires, implemented under the provider's own where +/// clause so a check can name the dependency a provider is missing. +/// +/// See [`IsProviderFor`](https://contextgeneric.dev/docs/reference/traits/wiring/is_provider_for). pub trait IsProviderFor {} diff --git a/crates/core/cgp-error/src/contexts/error_only.rs b/crates/core/cgp-error/src/contexts/error_only.rs index 59a5477ba..0e26e68da 100644 --- a/crates/core/cgp-error/src/contexts/error_only.rs +++ b/crates/core/cgp-error/src/contexts/error_only.rs @@ -3,6 +3,10 @@ use core::marker::PhantomData; use crate::HasErrorType; +/// The component that gives a context one abstract Error type, so fallible generic code never names +/// a concrete error and the context chooses it by wiring. +/// +/// See [`HasErrorType`](https://contextgeneric.dev/docs/reference/components/has_error_type). pub struct ErrorOnly(pub PhantomData); impl Default for ErrorOnly { diff --git a/crates/core/cgp-error/src/lib.rs b/crates/core/cgp-error/src/lib.rs index 2a16e422b..7304fd501 100644 --- a/crates/core/cgp-error/src/lib.rs +++ b/crates/core/cgp-error/src/lib.rs @@ -2,6 +2,7 @@ //! This crate provides CGP's error components: the abstract error type, raising, and wrapping. //! //! See [`HasErrorType`](https://contextgeneric.dev/docs/reference/components/has_error_type), [`CanRaiseError`](https://contextgeneric.dev/docs/reference/components/can_raise_error), and [`CanWrapError`](https://contextgeneric.dev/docs/reference/components/can_wrap_error). +#![warn(missing_docs)] mod contexts; mod traits; diff --git a/crates/core/cgp-error/src/traits/can_raise_error.rs b/crates/core/cgp-error/src/traits/can_raise_error.rs index 4e53be247..d925412b5 100644 --- a/crates/core/cgp-error/src/traits/can_raise_error.rs +++ b/crates/core/cgp-error/src/traits/can_raise_error.rs @@ -3,10 +3,10 @@ use cgp_macro::cgp_component; use crate::traits::has_error_type::HasErrorType; -/** - The `CanRaiseError` trait is used to raise any concrete error type into - an abstract error provided by [`HasErrorType`]. -*/ +/// The component that converts a concrete source error into the context's abstract error type, +/// dispatching per source error to the provider the context wires. +/// +/// See [`CanRaiseError`](https://contextgeneric.dev/docs/reference/components/can_raise_error). #[cgp_component(ErrorRaiser)] #[prefix(@cgp.core.error in DefaultNamespace)] #[derive_delegate(UseDelegate)] diff --git a/crates/core/cgp-error/src/traits/can_wrap_error.rs b/crates/core/cgp-error/src/traits/can_wrap_error.rs index cdbb446d7..a8a627821 100644 --- a/crates/core/cgp-error/src/traits/can_wrap_error.rs +++ b/crates/core/cgp-error/src/traits/can_wrap_error.rs @@ -3,10 +3,10 @@ use cgp_macro::cgp_component; use crate::traits::HasErrorType; -/** - The `CanWrapError` trait is used to attach a detail to an abstract error - provided by [`HasErrorType`]. -*/ +/// The component that folds a piece of detail, such as a message or a path, into an error the +/// context already holds, dispatching per detail type. +/// +/// See [`CanWrapError`](https://contextgeneric.dev/docs/reference/components/can_wrap_error). #[cgp_component(ErrorWrapper)] #[prefix(@cgp.core.error in DefaultNamespace)] #[derive_delegate(UseDelegate)] diff --git a/crates/core/cgp-error/src/traits/has_error_type.rs b/crates/core/cgp-error/src/traits/has_error_type.rs index a1e7f3572..b27fc6f4b 100644 --- a/crates/core/cgp-error/src/traits/has_error_type.rs +++ b/crates/core/cgp-error/src/traits/has_error_type.rs @@ -3,29 +3,16 @@ use core::fmt::Debug; use cgp::component::DefaultNamespace; use cgp_macro::cgp_type; -/** - The `HasErrorType` trait provides an abstract error type that can be used by - CGP components to decouple the code from any concrete error implementation. - - Although it is possible for each context to declare their own associated - `Error` type, doing so may result in having multiple ambiguous `Self::Error` types, - if there are multiple associated types with the same name in different traits. - - As a result, it is better for context traits to include `HasError` as their - parent traits, so that multiple traits can all refer to the same abstract - `Self::Error` type. - - The `Error` associated type is also required to implement [`Debug`]. - This is to allow `Self::Error` to be used in calls like `.unwrap()`, - as well as for simpler error logging. - - More details about how to use `HasErrorType` is available at - -*/ +/// The component that gives a context one abstract Error type, so fallible generic code never names +/// a concrete error and the context chooses it by wiring. +/// +/// See [`HasErrorType`](https://contextgeneric.dev/docs/reference/components/has_error_type). #[cgp_type] #[prefix(@cgp.core.error in DefaultNamespace)] pub trait HasErrorType { + /// The context's error type. type Error: Debug; } +/// The error type a context chooses. pub type ErrorOf = ::Error; diff --git a/crates/core/cgp-field/src/impls/build_from.rs b/crates/core/cgp-field/src/impls/build_from.rs index b59160679..9e8eb1e5a 100644 --- a/crates/core/cgp-field/src/impls/build_from.rs +++ b/crates/core/cgp-field/src/impls/build_from.rs @@ -3,9 +3,15 @@ use core::marker::PhantomData; use crate::traits::{BuildField, HasFields, IntoBuilder, TakeField}; use crate::types::{Cons, Field, Nil}; +/// Move every field of one record into another record's builder by field name, so several sources +/// can be merged before the target is finalized. +/// +/// See [`CanBuildFrom`](https://contextgeneric.dev/docs/reference/traits/casting/can_build_from). pub trait CanBuildFrom { + /// The built target. type Output; + /// Builds the target from the source. fn build_from(self, source: Source) -> Self::Output; } diff --git a/crates/core/cgp-field/src/impls/cast.rs b/crates/core/cgp-field/src/impls/cast.rs index 46bdac6a5..cc0e385f5 100644 --- a/crates/core/cgp-field/src/impls/cast.rs +++ b/crates/core/cgp-field/src/impls/cast.rs @@ -5,19 +5,38 @@ use crate::traits::{ }; use crate::types::{Either, Field, Void}; +/// Convert a narrow enum into a wider one that has every one of its variants, routing each by name +/// at the type level; the cast cannot fail. +/// +/// See [`CanUpcast`](https://contextgeneric.dev/docs/reference/traits/casting/can_upcast). pub trait CanUpcast { + /// Widens the value into the target. fn upcast(self, _tag: PhantomData) -> Target; } +/// Try to convert a wide enum into a narrower one, getting the narrowed value or a remainder with +/// the attempted variants ruled out for the next attempt. +/// +/// See [`CanDowncast`](https://contextgeneric.dev/docs/reference/traits/casting/can_downcast). pub trait CanDowncast { + /// The value left when the target does not match. type Remainder; + /// Narrows the value into the target. fn downcast(self, _tag: PhantomData) -> Result; } +/// Continue narrowing on the remainder a failed downcast hands back, so a value can be tried +/// against a second target and a third. Never used on its own. +/// +/// See +/// [`CanDowncastFields`](https://contextgeneric.dev/docs/reference/traits/casting/can_downcast_fields) +/// . pub trait CanDowncastFields { + /// The fields left when the target does not match. type Remainder; + /// Narrows the fields into the target. fn downcast_fields(self, _tag: PhantomData) -> Result; } @@ -57,9 +76,12 @@ where } } +/// Extracts a target's fields from a source. pub trait FieldsExtractor { + /// The source left when the target does not match. type Remainder; + /// Extracts the target from the source. fn extract_from(source: Source) -> Result; } diff --git a/crates/core/cgp-field/src/impls/chain.rs b/crates/core/cgp-field/src/impls/chain.rs index 3174bb0a8..96dfc49cf 100644 --- a/crates/core/cgp-field/src/impls/chain.rs +++ b/crates/core/cgp-field/src/impls/chain.rs @@ -3,6 +3,10 @@ use core::marker::PhantomData; use crate::traits::{FieldGetter, FieldMapper}; use crate::types::{Cons, Nil}; +/// The foundational getter that chains a list of field getters, so a getter component reads a field +/// several hops inside its context. +/// +/// See [`ChainGetters`](https://contextgeneric.dev/docs/reference/providers/chain_getters). pub struct ChainGetters(pub PhantomData); impl FieldGetter diff --git a/crates/core/cgp-field/src/impls/map_type.rs b/crates/core/cgp-field/src/impls/map_type.rs index fd975732c..6c2761af6 100644 --- a/crates/core/cgp-field/src/impls/map_type.rs +++ b/crates/core/cgp-field/src/impls/map_type.rs @@ -1,24 +1,28 @@ use crate::traits::MapType; use crate::types::Void; +/// Maps a type to itself. pub struct IsPresent; impl MapType for IsPresent { type Map = T; } +/// Maps a type to `()`. pub struct IsNothing; impl MapType for IsNothing { type Map = (); } +/// Maps a type to [`Void`]. pub struct IsVoid; impl MapType for IsVoid { type Map = Void; } +/// Maps a type to `Option`. pub struct IsOptional; impl MapType for IsOptional { diff --git a/crates/core/cgp-field/src/impls/map_type_ref.rs b/crates/core/cgp-field/src/impls/map_type_ref.rs index aec6696ba..25abbeda0 100644 --- a/crates/core/cgp-field/src/impls/map_type_ref.rs +++ b/crates/core/cgp-field/src/impls/map_type_ref.rs @@ -1,17 +1,20 @@ use crate::traits::MapTypeRef; +/// Maps a type to a shared reference. pub struct IsRef; impl MapTypeRef for IsRef { type Map<'a, T: 'a> = &'a T; } +/// Maps a type to a mutable reference. pub struct IsMut; impl MapTypeRef for IsMut { type Map<'a, T: 'a> = &'a mut T; } +/// Maps a type to itself. pub struct IsOwned; impl MapTypeRef for IsOwned { diff --git a/crates/core/cgp-field/src/impls/use_field.rs b/crates/core/cgp-field/src/impls/use_field.rs index 0fd374715..a45f7f64a 100644 --- a/crates/core/cgp-field/src/impls/use_field.rs +++ b/crates/core/cgp-field/src/impls/use_field.rs @@ -5,58 +5,16 @@ use cgp_type::{TypeProvider, TypeProviderComponent}; use crate::traits::{FieldGetter, HasField, HasFieldMut, MutFieldGetter}; -/** - The `UseField` pattern is used to implement a CGP getter trait by reading - the `Tag` field from `Context` via the [`HasField`] trait. - - When a CGP getter component contains only one getter method and is defined - using the `#[cgp_getter]` macro, a `UseField` implementation is automatically - generated. - - Typically, the `Tag` type would be a type-level string defined through - the `Symbol!` macro, such as `Symbol!("name")`. It may also be a type-level - integer that is wrapped in the `Index` type, such as `Index<0>`. - The `HasField` implementation for these tag types would be automatically - implemented following the field names in the struct when `#[derive(HasField)]` - is used. - - However, users are free to use any type as the `Tag` type, as there is no - additional constraints on what the type should be. The only consequence is - that such manual tags would not be automatically implemented by - `#[derive(HasField)]`, and so users would have to manually implement the - `HasField` instances, or generate them from a different macro. - - `UseField` allows users to easily implement a getter trait for a context - by only having to derive the [`HasField`] trait, and specifying the field - name through `UseField`. This reduces the amount of boilerplate code required - to manually implement the getter trait for each concrete context. - - ## Example - - Given the following getter component definition: - - ```rust,ignore - #[cgp_getter(NameGetter)] - pub trait HasName { - fn name(&self) -> &str; - } - ``` - - The following `UseField` implementation would be generated: - - ```rust,ignore - impl NameGetter for UseField - where - Context: HasField, - { - fn name(context: &Context) -> &str { - &context.get_field(PhantomData).as_str() - } - } - ``` -*/ +/// The provider that implements a getter by reading the context field a type-level tag names, so +/// the field name is a wiring choice, not the method name. +/// +/// See [`UseField`](https://contextgeneric.dev/docs/reference/providers/use_field). pub struct UseField(pub PhantomData); +/// The alias WithProvider``>: a single-method getter reads the field Tag names, and a +/// `#[cgp_type]` component takes that field's type. +/// +/// See [`WithField`](https://contextgeneric.dev/docs/reference/providers/with_field). pub type WithField = WithProvider>; impl TypeProvider for UseField diff --git a/crates/core/cgp-field/src/impls/use_ref.rs b/crates/core/cgp-field/src/impls/use_ref.rs index cfd850144..c23c11f18 100644 --- a/crates/core/cgp-field/src/impls/use_ref.rs +++ b/crates/core/cgp-field/src/impls/use_ref.rs @@ -4,8 +4,16 @@ use cgp_component::WithProvider; use crate::traits::{FieldGetter, HasField, HasFieldMut, MutFieldGetter}; +/// The foundational field getter that borrows a field through AsRef or AsMut as a different type, +/// wired to a getter through the WithFieldRef alias. +/// +/// See [`UseFieldRef`](https://contextgeneric.dev/docs/reference/providers/use_field_ref). pub struct UseFieldRef(pub PhantomData<(Tag, Value)>); +/// The alias WithProvider``>: a getter returning &Value reads a field whose +/// stored type implements AsRef``. +/// +/// See [`WithFieldRef`](https://contextgeneric.dev/docs/reference/providers/with_field_ref). pub type WithFieldRef = WithProvider>; impl FieldGetter for UseFieldRef diff --git a/crates/core/cgp-field/src/lib.rs b/crates/core/cgp-field/src/lib.rs index 7e9913326..7e3dad289 100644 --- a/crates/core/cgp-field/src/lib.rs +++ b/crates/core/cgp-field/src/lib.rs @@ -3,7 +3,11 @@ //! and the structural casts. //! //! See [`HasField`](https://contextgeneric.dev/docs/reference/traits/field-access/has_field), [`Index`](https://contextgeneric.dev/docs/reference/types/index_type), [`MRef`](https://contextgeneric.dev/docs/reference/types/mref), and the [casts](https://contextgeneric.dev/docs/reference/traits/casting/). +#![warn(missing_docs)] +/// The field traits' implementations and the built-in providers. pub mod impls; +/// The field traits: access, building, casting, and the type-level lists. pub mod traits; +/// The field types: tags, lists, sums, and the owned-or-borrowed value. pub mod types; diff --git a/crates/core/cgp-field/src/traits/append_product.rs b/crates/core/cgp-field/src/traits/append_product.rs index a2aae98c9..255838442 100644 --- a/crates/core/cgp-field/src/traits/append_product.rs +++ b/crates/core/cgp-field/src/traits/append_product.rs @@ -1,6 +1,12 @@ use crate::types::{Cons, Nil}; +/// Name the type-level product list with one more entry at the end, so generic code can describe in +/// a signature the shape it will produce. +/// +/// See +/// [`AppendProduct`](https://contextgeneric.dev/docs/reference/traits/type-level/append_product) . pub trait AppendProduct { + /// The list with the item appended. type Output; } diff --git a/crates/core/cgp-field/src/traits/build_field.rs b/crates/core/cgp-field/src/traits/build_field.rs index 23bfac1e4..032f8c0de 100644 --- a/crates/core/cgp-field/src/traits/build_field.rs +++ b/crates/core/cgp-field/src/traits/build_field.rs @@ -3,11 +3,18 @@ use core::marker::PhantomData; use crate::impls::{IsNothing, IsPresent}; use crate::traits::{PartialData, UpdateField}; +/// Set a currently-absent field on a partial record, which is the direction of the builder family +/// you write most when assembling a struct field by field. +/// +/// See [`BuildField`](https://contextgeneric.dev/docs/reference/traits/builder/build_field). pub trait BuildField { + /// The field's value type. type Value; + /// The record with the field built. type Output; + /// Builds the field. fn build_field(self, _tag: PhantomData, value: Self::Value) -> Self::Output; } @@ -24,6 +31,11 @@ where } } +/// Turn a partial record with every field present back into the concrete struct; the impl exists +/// only at that configuration. +/// +/// See [`FinalizeBuild`](https://contextgeneric.dev/docs/reference/traits/builder/finalize_build). pub trait FinalizeBuild: PartialData { + /// Finalizes the builder. fn finalize_build(self) -> Self::Target; } diff --git a/crates/core/cgp-field/src/traits/concat_product.rs b/crates/core/cgp-field/src/traits/concat_product.rs index 39d01911b..07c7b6b3a 100644 --- a/crates/core/cgp-field/src/traits/concat_product.rs +++ b/crates/core/cgp-field/src/traits/concat_product.rs @@ -1,6 +1,12 @@ use crate::types::{Cons, Nil}; +/// Name the type-level product list formed by one product's entries followed by another's, the +/// general form of appending a single entry. +/// +/// See +/// [`ConcatProduct`](https://contextgeneric.dev/docs/reference/traits/type-level/concat_product) . pub trait ConcatProduct { + /// The concatenated list. type Output; } diff --git a/crates/core/cgp-field/src/traits/extract_field.rs b/crates/core/cgp-field/src/traits/extract_field.rs index 0e79810f9..373d9bc0f 100644 --- a/crates/core/cgp-field/src/traits/extract_field.rs +++ b/crates/core/cgp-field/src/traits/extract_field.rs @@ -3,39 +3,75 @@ use core::marker::PhantomData; use crate::types::Void; +/// Turn an enum into the extractor the variant-narrowing traits operate on, and back, since +/// ExtractField narrows an extractor rather than an enum. +/// +/// See [`HasExtractor`](https://contextgeneric.dev/docs/reference/traits/variant/has_extractor). pub trait HasExtractor { + /// The extractor type. type Extractor; + /// Converts the value into an extractor. fn to_extractor(self) -> Self::Extractor; + /// Rebuilds the value from an extractor. fn from_extractor(extractor: Self::Extractor) -> Self; } +/// Obtain an extractor that borrows an enum, so its variants can be matched by name with payloads +/// as shared references and the value left intact. +/// +/// See +/// [`HasExtractorRef`](https://contextgeneric.dev/docs/reference/traits/variant/has_extractor_ref) +/// . pub trait HasExtractorRef { + /// The borrowed extractor type. type ExtractorRef<'a> where Self: 'a; + /// Borrows the value as an extractor. fn extractor_ref(&self) -> Self::ExtractorRef<'_>; } +/// Obtain an extractor that borrows an enum mutably, so a named variant's payload can be changed in +/// place without consuming or rebuilding the value. +/// +/// See +/// [`HasExtractorMut`](https://contextgeneric.dev/docs/reference/traits/variant/has_extractor_mut) +/// . pub trait HasExtractorMut { + /// The mutably borrowed extractor type. type ExtractorMut<'a> where Self: 'a; + /// Borrows the value mutably as an extractor. fn extractor_mut(&mut self) -> Self::ExtractorMut<'_>; } +/// Try one named variant of an enum's extractor, getting its payload or a remainder with that +/// variant ruled out, so a chain ends in a proven-exhaustive match. +/// +/// See [`ExtractField`](https://contextgeneric.dev/docs/reference/traits/variant/extract_field). pub trait ExtractField { + /// The field's value type. type Value; + /// The value left when the field does not match. type Remainder; + /// Extracts the field. fn extract_field(self, _tag: PhantomData) -> Result; } +/// Discharge an extractor with every variant ruled out: its type is uninhabited, so the method +/// returns any type and closes the match without a wildcard. +/// +/// See +/// [`FinalizeExtract`](https://contextgeneric.dev/docs/reference/traits/variant/finalize_extract) . pub trait FinalizeExtract { + /// Finalizes the extraction. fn finalize_extract(self) -> T; } @@ -51,9 +87,17 @@ impl FinalizeExtract for Infallible { } } +/// Collapse the Result the last step of an extraction chain returns, returning the payload and +/// discharging the uninhabited remainder at the type level. +/// +/// See +/// [`FinalizeExtractResult`](https://contextgeneric.dev/docs/reference/traits/variant/finalize_extract_result) +/// . pub trait FinalizeExtractResult { + /// The extracted value. type Output; + /// Finalizes the result. fn finalize_extract_result(self) -> Self::Output; } diff --git a/crates/core/cgp-field/src/traits/from_fields.rs b/crates/core/cgp-field/src/traits/from_fields.rs index 10d6c4839..d85d1e800 100644 --- a/crates/core/cgp-field/src/traits/from_fields.rs +++ b/crates/core/cgp-field/src/traits/from_fields.rs @@ -1,5 +1,10 @@ use crate::traits::HasFields; +/// Rebuild a concrete struct or enum from the anonymous shape ToFields produced, as the return +/// journey of a structural operation. +/// +/// See [`FromFields`](https://contextgeneric.dev/docs/reference/traits/shape/from_fields). pub trait FromFields: HasFields { + /// Builds the value from the fields. fn from_fields(fields: Self::Fields) -> Self; } diff --git a/crates/core/cgp-field/src/traits/from_variant.rs b/crates/core/cgp-field/src/traits/from_variant.rs index 82ce130b4..58c6e147e 100644 --- a/crates/core/cgp-field/src/traits/from_variant.rs +++ b/crates/core/cgp-field/src/traits/from_variant.rs @@ -1,7 +1,13 @@ use core::marker::PhantomData; +/// Construct an enum from a single variant chosen by its type-level name, so generic code can build +/// a variant it cannot name as a constructor. +/// +/// See [`FromVariant`](https://contextgeneric.dev/docs/reference/traits/variant/from_variant). pub trait FromVariant { + /// The variant's payload type. type Value; + /// Builds the variant. fn from_variant(_tag: PhantomData, value: Self::Value) -> Self; } diff --git a/crates/core/cgp-field/src/traits/has_builder.rs b/crates/core/cgp-field/src/traits/has_builder.rs index c657acaf3..d8784016a 100644 --- a/crates/core/cgp-field/src/traits/has_builder.rs +++ b/crates/core/cgp-field/src/traits/has_builder.rs @@ -1,11 +1,23 @@ +/// Start an empty builder for a record, as the entry point to assembling a struct field by field +/// rather than through a struct literal that names the type. +/// +/// See [`HasBuilder`](https://contextgeneric.dev/docs/reference/traits/builder/has_builder). pub trait HasBuilder { + /// The builder type. type Builder; + /// Creates an empty builder. fn builder() -> Self::Builder; } +/// Turn a complete record into a partial one with every field present, to take fields out and put +/// them back without naming the concrete type. +/// +/// See [`IntoBuilder`](https://contextgeneric.dev/docs/reference/traits/builder/into_builder). pub trait IntoBuilder { + /// The builder type. type Builder; + /// Converts the value into a builder. fn into_builder(self) -> Self::Builder; } diff --git a/crates/core/cgp-field/src/traits/has_field.rs b/crates/core/cgp-field/src/traits/has_field.rs index 2aa3c900b..e89181cea 100644 --- a/crates/core/cgp-field/src/traits/has_field.rs +++ b/crates/core/cgp-field/src/traits/has_field.rs @@ -3,55 +3,27 @@ use core::ops::Deref; use cgp_component::UseContext; -/** - The `HasField` trait is used to implement getter methods for a type that - derives the trait. - - When a struct uses `#[derive(HasField)]`, the macro would generate a `HasField` - implementation for each field in the struct, with the field name becoming a - type-level string to be used in the generic `Tag` parameter. - - ## Example - - Given the following struct: - - ```rust,ignore - #[derive(HasField)] - pub struct Person { - pub name: String, - pub age: u8, - } - ``` - - The macro would generate the following implementation: - - ```rust,ignore - impl HasField for Person { - type Value = String; - - fn get_field(&self, _tag: PhantomData) -> &Self::Value { - &self.name - } - } - - impl HasField for Person { - type Value = u8; - - fn get_field(&self, _tag: PhantomData) -> &Self::Value { - &self.age - } - } - ``` -*/ +/// The trait for reading one field of a context by its name as a type, so generic code can bound on +/// a field of a type it cannot name. +/// +/// See [`HasField`](https://contextgeneric.dev/docs/reference/traits/field-access/has_field). pub trait HasField { + /// The field's value type. type Value; + /// Reads the field. fn get_field(&self, _tag: PhantomData) -> &Self::Value; } +/// The provider-side form of HasField: a getter component takes any FieldGetter provider, such as +/// UseField, through WithProvider. +/// +/// See [`FieldGetter`](https://contextgeneric.dev/docs/reference/traits/field-access/field_getter). pub trait FieldGetter { + /// The field's value type. type Value; + /// Reads the field. fn get_field(context: &Context, _tag: PhantomData) -> &Self::Value; } diff --git a/crates/core/cgp-field/src/traits/has_field_mut.rs b/crates/core/cgp-field/src/traits/has_field_mut.rs index 56f76c992..40c798126 100644 --- a/crates/core/cgp-field/src/traits/has_field_mut.rs +++ b/crates/core/cgp-field/src/traits/has_field_mut.rs @@ -3,11 +3,24 @@ use core::ops::DerefMut; use crate::traits::{FieldGetter, HasField}; +/// Mutable tag-keyed field access, letting an implementation change a field of a context it cannot +/// name, as the mutable counterpart of HasField. +/// +/// See [`HasFieldMut`](https://contextgeneric.dev/docs/reference/traits/field-access/has_field_mut) +/// . pub trait HasFieldMut: HasField { + /// Mutably reads the field. fn get_field_mut(&mut self, tag: PhantomData) -> &mut Self::Value; } +/// The provider-side form of HasFieldMut: a getter with a &mut self method takes any MutFieldGetter +/// provider, such as UseField, through WithProvider. +/// +/// See +/// [`MutFieldGetter`](https://contextgeneric.dev/docs/reference/traits/field-access/mut_field_getter) +/// . pub trait MutFieldGetter: FieldGetter { + /// Mutably reads the field. fn get_field_mut(context: &mut Context, tag: PhantomData) -> &mut Self::Value; } diff --git a/crates/core/cgp-field/src/traits/has_fields.rs b/crates/core/cgp-field/src/traits/has_fields.rs index 0d2ae6933..a7196ac73 100644 --- a/crates/core/cgp-field/src/traits/has_fields.rs +++ b/crates/core/cgp-field/src/traits/has_fields.rs @@ -1,8 +1,18 @@ +/// Name a type's whole shape as a single type, every field with its name and type, so generic code +/// can walk a struct or enum it cannot name. +/// +/// See [`HasFields`](https://contextgeneric.dev/docs/reference/traits/shape/has_fields). pub trait HasFields { + /// The type's field list. type Fields; } +/// Name a type's whole shape with every value borrowed, so generic code can read a struct or enum +/// without consuming it. Derived rather than written. +/// +/// See [`HasFieldsRef`](https://contextgeneric.dev/docs/reference/traits/shape/has_fields_ref). pub trait HasFieldsRef { + /// The borrowed field list. type FieldsRef<'a> where Self: 'a; diff --git a/crates/core/cgp-field/src/traits/map_field.rs b/crates/core/cgp-field/src/traits/map_field.rs index 2175aa78a..73991dec3 100644 --- a/crates/core/cgp-field/src/traits/map_field.rs +++ b/crates/core/cgp-field/src/traits/map_field.rs @@ -2,13 +2,12 @@ use core::marker::PhantomData; use crate::traits::{FieldGetter, HasField}; -/** - A helper trait to help organize the lifetime inference in Rust. - Without this, `Self::Value` would need to be `'static`, as Rust couldn't - infer the correct lifetime when calling chained field getters, such as - `context.get_field().get_field()`. -*/ +/// A blanket helper on every HasField that passes a borrowed field to a closure, so generic code +/// can read a field of a field without a lifetime bound. +/// +/// See [`MapField`](https://contextgeneric.dev/docs/reference/traits/field-access/map_field). pub trait MapField: HasField { + /// Maps the field's value. fn map_field( &self, _tag: PhantomData, @@ -30,10 +29,12 @@ where } } -/** - The provider trait equivalent of [`MapField`]. -*/ +/// The provider-side mirror of MapField, a blanket impl over every field getter that lets a getter +/// provider read through the field another provider returns. +/// +/// See [`FieldMapper`](https://contextgeneric.dev/docs/reference/traits/field-access/field_mapper). pub trait FieldMapper: FieldGetter { + /// Maps the field's value. fn map_field( context: &Context, _tag: PhantomData, diff --git a/crates/core/cgp-field/src/traits/map_fields.rs b/crates/core/cgp-field/src/traits/map_fields.rs index 218257ee9..3d0dbaa04 100644 --- a/crates/core/cgp-field/src/traits/map_fields.rs +++ b/crates/core/cgp-field/src/traits/map_fields.rs @@ -1,7 +1,12 @@ use crate::traits::MapType; use crate::types::{Cons, Either, Nil, Void}; +/// Rewrite every entry of a type-level product or sum through one MapType marker, as CGP does to +/// wrap each provider in a pipeline's list. +/// +/// See [`MapFields`](https://contextgeneric.dev/docs/reference/traits/type-level/map_fields). pub trait MapFields { + /// The mapped field list. type Mapped; } diff --git a/crates/core/cgp-field/src/traits/map_type.rs b/crates/core/cgp-field/src/traits/map_type.rs index fbea5afea..36ed87009 100644 --- a/crates/core/cgp-field/src/traits/map_type.rs +++ b/crates/core/cgp-field/src/traits/map_type.rs @@ -1,3 +1,8 @@ +/// The marker trait whose Map`` decides how one field of a partial record or enum is stored: its +/// value, nothing, an uninhabited type, or an Option. +/// +/// See [`MapType`](https://contextgeneric.dev/docs/reference/traits/type-level/map_type). pub trait MapType { + /// The mapped type. type Map; } diff --git a/crates/core/cgp-field/src/traits/map_type_ref.rs b/crates/core/cgp-field/src/traits/map_type_ref.rs index 740d92fe6..f03fca924 100644 --- a/crates/core/cgp-field/src/traits/map_type_ref.rs +++ b/crates/core/cgp-field/src/traits/map_type_ref.rs @@ -1,3 +1,8 @@ +/// The marker trait deciding how a borrowed extractor holds each payload, by shared reference, by +/// mutable reference, or by value, at a lifetime. +/// +/// See [`MapTypeRef`](https://contextgeneric.dev/docs/reference/traits/type-level/map_type_ref). pub trait MapTypeRef { + /// The mapped borrowed type. type Map<'a, T: 'a>: 'a; } diff --git a/crates/core/cgp-field/src/traits/option_as_ref.rs b/crates/core/cgp-field/src/traits/option_as_ref.rs index a7753a2c1..4f1a8f390 100644 --- a/crates/core/cgp-field/src/traits/option_as_ref.rs +++ b/crates/core/cgp-field/src/traits/option_as_ref.rs @@ -1,9 +1,12 @@ -/// Borrows the value inside an `Option` as a `&T`. +/// Borrow the value inside an Option as a &T, the bound an Option`<&str>` implicit argument +/// generates so the field may be a String, a Cow``, or a Box``. /// /// The blanket impl covers any `Option` whose `U` implements `AsRef`, so an -/// `#[implicit] nickname: Option<&str>` argument reads an `Option`, an -/// `Option>`, or an `Option>` field without needing an allocator -/// of its own. +/// `#[implicit] nickname: Option<&str>` argument reads an `Option` field +/// without needing an allocator. +/// +/// See [`OptionAsRef`](https://contextgeneric.dev/docs/reference/traits/field-access/option_as_ref) +/// . pub trait OptionAsRef { /// Borrows the contained value, or `None` when the option is empty. fn option_as_ref(&self) -> Option<&T>; diff --git a/crates/core/cgp-field/src/traits/partial_data.rs b/crates/core/cgp-field/src/traits/partial_data.rs index 06e5ff389..c3fd6e16b 100644 --- a/crates/core/cgp-field/src/traits/partial_data.rs +++ b/crates/core/cgp-field/src/traits/partial_data.rs @@ -1,3 +1,8 @@ +/// Name the concrete struct a partial record will become, at every configuration, so generic code +/// can mention the destination mid-build. +/// +/// See [`PartialData`](https://contextgeneric.dev/docs/reference/traits/builder/partial_data). pub trait PartialData { + /// The target the partial value builds. type Target; } diff --git a/crates/core/cgp-field/src/traits/static_string.rs b/crates/core/cgp-field/src/traits/static_string.rs index 1bd2b3523..a600614a0 100644 --- a/crates/core/cgp-field/src/traits/static_string.rs +++ b/crates/core/cgp-field/src/traits/static_string.rs @@ -1,6 +1,11 @@ use crate::types::{Chars, Nil, Symbol}; +/// Decode a Symbol into a compile-time &'static str constant, the eager way to recover a field or +/// variant name as data. +/// +/// See [`StaticString`](https://contextgeneric.dev/docs/reference/traits/formatting/static_string). pub trait StaticString { + /// The string's value. const VALUE: &'static str; } diff --git a/crates/core/cgp-field/src/traits/take_field.rs b/crates/core/cgp-field/src/traits/take_field.rs index 0f715c956..60469a162 100644 --- a/crates/core/cgp-field/src/traits/take_field.rs +++ b/crates/core/cgp-field/src/traits/take_field.rs @@ -3,11 +3,18 @@ use core::marker::PhantomData; use crate::impls::{IsNothing, IsPresent}; use crate::traits::UpdateField; +/// Take a present field out of a partial record, getting the value and a remainder that cannot be +/// finalized until the field is put back. +/// +/// See [`TakeField`](https://contextgeneric.dev/docs/reference/traits/builder/take_field). pub trait TakeField { + /// The field's value type. type Value; + /// The value left after the field is taken. type Remainder; + /// Takes the field. fn take_field(self, _tag: PhantomData) -> (Self::Value, Self::Remainder); } diff --git a/crates/core/cgp-field/src/traits/to_fields.rs b/crates/core/cgp-field/src/traits/to_fields.rs index f320f8d24..5317ecba3 100644 --- a/crates/core/cgp-field/src/traits/to_fields.rs +++ b/crates/core/cgp-field/src/traits/to_fields.rs @@ -1,10 +1,20 @@ use crate::traits::{HasFields, HasFieldsRef}; +/// Produce a value in the shape HasFields names, taking a struct or enum apart into an anonymous +/// list of named entries. +/// +/// See [`ToFields`](https://contextgeneric.dev/docs/reference/traits/shape/to_fields). pub trait ToFields: HasFields { + /// Converts the value into its fields. fn to_fields(self) -> Self::Fields; } +/// Walk a value's shape without consuming it, for code that only reads the fields of a struct or +/// enum it cannot name. +/// +/// See [`ToFieldsRef`](https://contextgeneric.dev/docs/reference/traits/shape/to_fields_ref). pub trait ToFieldsRef: HasFieldsRef { + /// Borrows the value as its fields. fn to_fields_ref<'a>(&'a self) -> Self::FieldsRef<'a> where Self: 'a; diff --git a/crates/core/cgp-field/src/traits/transform_map.rs b/crates/core/cgp-field/src/traits/transform_map.rs index 8f4013bf1..3820d2c0e 100644 --- a/crates/core/cgp-field/src/traits/transform_map.rs +++ b/crates/core/cgp-field/src/traits/transform_map.rs @@ -4,14 +4,26 @@ use crate::impls::IsNothing; use crate::traits::{HasFields, MapType, PartialData, UpdateField}; use crate::types::{Cons, Field, Nil}; -/// Natural transformation from `M1::Map` to `M2::Map` +/// The per-field function converting a value from one marker's storage to another's, and the +/// extension point for a new way to re-mark a record. +/// +/// See [`TransformMap`](https://contextgeneric.dev/docs/reference/traits/type-level/transform_map). pub trait TransformMap { + /// Transforms the mapped value. fn transform_mapped(value: M1::Map) -> M2::Map; } +/// Apply one per-field transform across a whole partial record, re-marking every field to a target +/// marker in one call; the optional layer is built on it. +/// +/// See +/// [`TransformMapFields`](https://contextgeneric.dev/docs/reference/traits/type-level/transform_map_fields) +/// . pub trait TransformMapFields { + /// The transformed value. type Output; + /// Transforms the fields. fn transform_map_fields(self) -> Self::Output; } diff --git a/crates/core/cgp-field/src/traits/update_field.rs b/crates/core/cgp-field/src/traits/update_field.rs index 602a9cc85..544589736 100644 --- a/crates/core/cgp-field/src/traits/update_field.rs +++ b/crates/core/cgp-field/src/traits/update_field.rs @@ -2,13 +2,21 @@ use core::marker::PhantomData; use crate::traits::MapType; +/// The per-field primitive of the builder family: change one field's presence marker and hand back +/// what was stored there before. +/// +/// See [`UpdateField`](https://contextgeneric.dev/docs/reference/traits/builder/update_field). pub trait UpdateField { + /// The field's value type. type Value; + /// The mapper the update returns. type Mapper: MapType; + /// The value with the field updated. type Output; + /// Updates the field. fn update_field( self, _tag: PhantomData, diff --git a/crates/core/cgp-field/src/types/field.rs b/crates/core/cgp-field/src/types/field.rs index 092381865..9b0c43387 100644 --- a/crates/core/cgp-field/src/types/field.rs +++ b/crates/core/cgp-field/src/types/field.rs @@ -1,41 +1,14 @@ use core::fmt::Debug; use core::marker::PhantomData; -/** - The `Field` type is used to represent a _named_ field entry - within a product type or a sum type. - - `Field` is parameterized by a phantom `Tag` type, which is used to represent - the field name as type. Typically, this would either be a type-level string - such as `Symbol!("name")`, or a type-level index such as `Index<0>`. - Aside from that, `Field` is essentially a wrapper around `Value`. - - `Field` is mainly used within the derived [`HasFields`](crate::traits::HasFields) - implementations, to include the field name in the generic product or sum - representation of the given struct or enum. - - ## Example - - Given the following struct definition: - - ```rust,ignore - #[derive(HasFields)] - pub struct MyContext { - pub name: String, - pub age: u8, - } - ``` - - The following `HasFields` implementation would be generated: - - ```rust,ignore - impl HasFields for MyContext { - type Fields = Product![Field, Field]; - } - ``` -*/ +/// A value paired with its type-level name tag, so a struct's fields and an enum's variants can be +/// described one named entry at a time. +/// +/// See [`Field`](https://contextgeneric.dev/docs/reference/types/field). pub struct Field { + /// The field's value. pub value: Value, + /// The field's type-level tag. pub phantom: PhantomData, } diff --git a/crates/core/cgp-field/src/types/index.rs b/crates/core/cgp-field/src/types/index.rs index d8d46219b..a13d3a497 100644 --- a/crates/core/cgp-field/src/types/index.rs +++ b/crates/core/cgp-field/src/types/index.rs @@ -1,33 +1,9 @@ use core::fmt::{Debug, Display}; -/** - The `Index` type is used to represent a `usize` value at - the _type level_. - - `Index` is simply defined to be parameterized by a _const-generic_ value - of type `usize`. It is most often used to access generic fields by their - _index_, instead of by their _name_. - - ## Example - - Given the following struct definition: - - ```rust,ignore - pub struct MyContext(pub u32); - ``` - - The following `HasField` implementation would be generated, with use of - `Index<0>` as the field tag: - - ```rust,ignore - impl HasField> for MyContext { - type Value = u32; - - fn get_field(&self) -> &u32 { - &self.0 - } - } -*/ +/// A number lifted into a type, so a tuple-struct field can be named by its position the way +/// Symbol! names a field by its string. +/// +/// See [`Index`](https://contextgeneric.dev/docs/reference/types/index_type). #[derive(Eq, PartialEq, Clone, Copy, Default)] pub struct Index; diff --git a/crates/core/cgp-field/src/types/life.rs b/crates/core/cgp-field/src/types/life.rs index b5420fbfa..019c27d83 100644 --- a/crates/core/cgp-field/src/types/life.rs +++ b/crates/core/cgp-field/src/types/life.rs @@ -1,3 +1,7 @@ use core::marker::PhantomData; +/// A lifetime lifted into a type, so a component's lifetime parameter can travel through the +/// dependency marker, whose parameters are types. +/// +/// See [`Life`](https://contextgeneric.dev/docs/reference/types/life). pub struct Life<'a>(pub PhantomData<*mut &'a ()>); diff --git a/crates/core/cgp-field/src/types/mref.rs b/crates/core/cgp-field/src/types/mref.rs index 385e706c4..d24268866 100644 --- a/crates/core/cgp-field/src/types/mref.rs +++ b/crates/core/cgp-field/src/types/mref.rs @@ -1,7 +1,13 @@ use core::ops::Deref; +/// A value that is either a borrow of a T or an owned T, so one getter signature serves both the +/// context that stores a value and the one that computes it. +/// +/// See [`MRef`](https://contextgeneric.dev/docs/reference/types/mref). pub enum MRef<'a, T> { + /// A borrowed value. Ref(&'a T), + /// An owned value. Owned(T), } @@ -38,6 +44,7 @@ impl MRef<'_, T> where T: Clone, { + /// Returns the value, cloning it when it is borrowed. pub fn get_or_clone(self) -> T { match self { Self::Ref(value) => value.clone(), diff --git a/crates/core/cgp-field/src/types/sum.rs b/crates/core/cgp-field/src/types/sum.rs index f2511c8b6..b28044b98 100644 --- a/crates/core/cgp-field/src/types/sum.rs +++ b/crates/core/cgp-field/src/types/sum.rs @@ -1,49 +1,18 @@ -/** - The `Either` type is used to represent an _anonymous sum type_. - - Similar to [`Cons`](crate::types::Cons), `Either` is used to form a sum type - by combining a chain of `Either` types, and terminated with a [`Void`] type. - But unlike product types, a sum type has values that belong to one - of the variants in the list. - - `Either` is most often used through the `Sum!` macro, which accepts a list of - types and turns them into a chain of `Either` types. - - ## Example - - Given the following sum type definition: - - ```rust,ignore - type MyUnion = Sum![u32, String, bool]; - ``` - - The following type would be generated: - - ```rust,ignore - type MyUnion = Either>>; - ``` -*/ +/// The head-or-rest cell of the type-level sum list, which describes an enum one variant at a time +/// so generic code can match any enum's variants. +/// +/// See [`Either`](https://contextgeneric.dev/docs/reference/types/either). #[derive(Eq, PartialEq, Debug, Clone)] pub enum Either { + /// The first alternative. Left(Head), + /// The remaining alternatives. Right(Tail), } -/** - The `Void` type is used to represent the end of an _anonymous sum type_, - or an _empty_ sum type. - - `Void` is commonly used as the `Tail` of a [`Either`] type, to terminate the list. - When used on its own, it represents an empty sum type, which can _never be constructed_. - - `Void` is functionally the same as the - [_never_ type](https://doc.rust-lang.org/std/primitive.never.html), `!`, - or otherwise - [`Infallible`](https://doc.rust-lang.org/std/convert/enum.Infallible.html). - However, we define a separate `Void` type, to make it more clear that it is - specifically used for terminating a sum type. - - Read more about sum types in [`Either`]. -*/ +/// The uninhabited end marker of the sum list: an empty enum that can never be constructed, which +/// lets a complete variant match end without a runtime branch. +/// +/// See [`Void`](https://contextgeneric.dev/docs/reference/types/void). #[derive(Eq, PartialEq, Debug, Clone)] pub enum Void {} diff --git a/crates/core/cgp-type/src/impls/use_delegated_type.rs b/crates/core/cgp-type/src/impls/use_delegated_type.rs index 9af562769..30aeefd31 100644 --- a/crates/core/cgp-type/src/impls/use_delegated_type.rs +++ b/crates/core/cgp-type/src/impls/use_delegated_type.rs @@ -6,8 +6,18 @@ use cgp_macro::cgp_provider; use crate::TypeProviderComponent; use crate::traits::TypeProvider; +/// The type provider that resolves an abstract type by looking its tag up in a delegate_components! +/// table, instead of fixing it to one concrete type. +/// +/// See [`UseDelegatedType`](https://contextgeneric.dev/docs/reference/providers/use_delegated_type) +/// . pub struct UseDelegatedType(pub PhantomData); +/// The alias WithProvider``>: several `#[cgp_type]` components answered +/// from one table keyed by their component markers. +/// +/// See +/// [`WithDelegatedType`](https://contextgeneric.dev/docs/reference/providers/with_delegated_type) . pub type WithDelegatedType = WithProvider>; #[cgp_provider(TypeProviderComponent)] diff --git a/crates/core/cgp-type/src/impls/use_type.rs b/crates/core/cgp-type/src/impls/use_type.rs index 59a129b3c..0d48162f8 100644 --- a/crates/core/cgp-type/src/impls/use_type.rs +++ b/crates/core/cgp-type/src/impls/use_type.rs @@ -6,36 +6,16 @@ use cgp_macro::cgp_provider; use crate::TypeProviderComponent; use crate::traits::TypeProvider; -/** - The `UseType` pattern is used to implement a CGP abstract type with the - specified `Type`. - - When a CGP type component is defined using the `#[cgp_type]` macro, a - provider implementation of `UseType` is automatically generated. - With `UseType`, users can instantiate an abstract type with the specified - `Type` without having to manually implement the given provider trait. - - ## Example - - Given the following type component definition: - - ```rust,ignore - #[cgp_type] - pub trait HasNameType { - type Name; - } - ``` - - The following `UseType` implementation would be generated: - - ```rust,ignore - impl NameTypeProvider for UseType { - type Name = Type; - } - ``` -*/ +/// The provider that sets an abstract-type component to a concrete type, so a context chooses its +/// error, scalar, or runtime type with one wiring line. +/// +/// See [`UseType`](https://contextgeneric.dev/docs/reference/providers/use_type). pub struct UseType(pub PhantomData); +/// The alias WithProvider``>, which binds an abstract-type component to a concrete type +/// exactly as the plain UseType`` does. +/// +/// See [`WithType`](https://contextgeneric.dev/docs/reference/providers/with_type). pub type WithType = WithProvider>; #[cgp_provider(TypeProviderComponent)] diff --git a/crates/core/cgp-type/src/lib.rs b/crates/core/cgp-type/src/lib.rs index e23b61ab1..fd135862c 100644 --- a/crates/core/cgp-type/src/lib.rs +++ b/crates/core/cgp-type/src/lib.rs @@ -2,6 +2,7 @@ //! This crate provides CGP's abstract types: a type the context chooses behind a trait. //! //! See [`HasType`](https://contextgeneric.dev/docs/reference/components/has_type), [`UseType`](https://contextgeneric.dev/docs/reference/providers/use_type), and [`UseDelegatedType`](https://contextgeneric.dev/docs/reference/providers/use_delegated_type). +#![warn(missing_docs)] mod impls; mod traits; diff --git a/crates/core/cgp-type/src/traits/has_type.rs b/crates/core/cgp-type/src/traits/has_type.rs index 24070b4ec..29cd60420 100644 --- a/crates/core/cgp-type/src/traits/has_type.rs +++ b/crates/core/cgp-type/src/traits/has_type.rs @@ -1,10 +1,16 @@ use cgp::macro_prelude::*; use cgp_macro::cgp_component; +/// CGP's tag-indexed abstract-type component: a context resolves one type per tag through wiring, +/// and generic code names it through TypeOf. +/// +/// See [`HasType`](https://contextgeneric.dev/docs/reference/components/has_type). #[cgp_component(TypeProvider)] #[derive_delegate(UseDelegate)] pub trait HasType { + /// The type the context chooses for the tag. type Type; } +/// The type a context chooses for a tag. pub type TypeOf = >::Type; diff --git a/crates/extra/cgp-dispatch/src/lib.rs b/crates/extra/cgp-dispatch/src/lib.rs index 794d51ce2..7db2541e4 100644 --- a/crates/extra/cgp-dispatch/src/lib.rs +++ b/crates/extra/cgp-dispatch/src/lib.rs @@ -4,6 +4,7 @@ //! to a handler. //! //! See [`MatchWithHandlers`](https://contextgeneric.dev/docs/reference/providers/dispatch/match_with_handlers), [`MatchWithValueHandlers`](https://contextgeneric.dev/docs/reference/providers/dispatch/match_with_value_handlers), and [`ExtractFieldAndHandle`](https://contextgeneric.dev/docs/reference/providers/dispatch/extract_field_and_handle). +#![warn(missing_docs)] mod providers; diff --git a/crates/extra/cgp-dispatch/src/providers/builders/build_and_merge_outputs.rs b/crates/extra/cgp-dispatch/src/providers/builders/build_and_merge_outputs.rs index 696152e1b..61cbf6d24 100644 --- a/crates/extra/cgp-dispatch/src/providers/builders/build_and_merge_outputs.rs +++ b/crates/extra/cgp-dispatch/src/providers/builders/build_and_merge_outputs.rs @@ -22,6 +22,7 @@ delegate_components! { } } +/// Maps each handler to a [`BuildAndMerge`] wrapper. pub struct ToBuildAndMergeHandler; impl MapType for ToBuildAndMergeHandler { diff --git a/crates/extra/cgp-dispatch/src/providers/dispatchers/dispatch_matchers.rs b/crates/extra/cgp-dispatch/src/providers/dispatchers/dispatch_matchers.rs index f23ea0e67..b3381db26 100644 --- a/crates/extra/cgp-dispatch/src/providers/dispatchers/dispatch_matchers.rs +++ b/crates/extra/cgp-dispatch/src/providers/dispatchers/dispatch_matchers.rs @@ -1,4 +1,5 @@ use cgp_monad::monadic::ok::OkMonadic; use cgp_monad::providers::PipeMonadic; +/// Dispatches a value through a list of matchers. pub type DispatchMatchers = PipeMonadic; diff --git a/crates/extra/cgp-dispatch/src/providers/field_builders/build_and_merge.rs b/crates/extra/cgp-dispatch/src/providers/field_builders/build_and_merge.rs index e440847dd..1cf203ec0 100644 --- a/crates/extra/cgp-dispatch/src/providers/field_builders/build_and_merge.rs +++ b/crates/extra/cgp-dispatch/src/providers/field_builders/build_and_merge.rs @@ -4,6 +4,12 @@ use cgp_handler::{ Computer, ComputerComponent, Handler, HandlerComponent, TryComputer, TryComputerComponent, }; +/// The builder step that builds a sub-record with a provider and moves every one of its fields into +/// the target's partial record at once. +/// +/// See +/// [`BuildAndMerge`](https://contextgeneric.dev/docs/reference/providers/dispatch/build_and_merge) +/// . pub struct BuildAndMerge(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/field_builders/build_and_set_field.rs b/crates/extra/cgp-dispatch/src/providers/field_builders/build_and_set_field.rs index 0532a8a94..786cba221 100644 --- a/crates/extra/cgp-dispatch/src/providers/field_builders/build_and_set_field.rs +++ b/crates/extra/cgp-dispatch/src/providers/field_builders/build_and_set_field.rs @@ -3,6 +3,12 @@ use cgp_handler::{ Computer, ComputerComponent, Handler, HandlerComponent, TryComputer, TryComputerComponent, }; +/// The builder step that computes one field's value from a provider, which can read the fields +/// already set, and sets it on the partial record. +/// +/// See +/// [`BuildAndSetField`](https://contextgeneric.dev/docs/reference/providers/dispatch/build_and_set_field) +/// . pub struct BuildAndSetField(pub PhantomData<(Tag, Provider)>); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_field.rs b/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_field.rs index 05313bdb6..e9c000f1d 100644 --- a/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_field.rs +++ b/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_field.rs @@ -1,6 +1,12 @@ use cgp::prelude::*; use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerComponent}; +/// The matcher adapter that tries one variant, hands its payload to an inner provider on a match, +/// and passes the remainder on when the variant does not match. +/// +/// See +/// [`ExtractFieldAndHandle`](https://contextgeneric.dev/docs/reference/providers/dispatch/extract_field_and_handle) +/// . pub struct ExtractFieldAndHandle(pub PhantomData<(Tag, Provider)>); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_first_field.rs b/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_first_field.rs index 1fdab5f50..7f956c1e6 100644 --- a/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_first_field.rs +++ b/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_first_field.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerComponent}; +/// Extracts the first field of a pair and handles it. pub struct ExtractFirstFieldAndHandle(pub PhantomData<(Tag, Provider)>); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_handle.rs b/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_handle.rs index a37d6a651..9732283bf 100644 --- a/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_handle.rs +++ b/crates/extra/cgp-dispatch/src/providers/field_matchers/extract_handle.rs @@ -2,6 +2,12 @@ use cgp::field::impls::CanDowncastFields; use cgp::prelude::*; use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerComponent}; +/// The matcher adapter that narrows an enum to a smaller enum of some of its variants and hands +/// that whole group to one inner provider. +/// +/// See +/// [`DowncastAndHandle`](https://contextgeneric.dev/docs/reference/providers/dispatch/downcast_and_handle) +/// . pub struct DowncastAndHandle(pub PhantomData<(Input, Provider)>); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/field_matchers/field_value.rs b/crates/extra/cgp-dispatch/src/providers/field_matchers/field_value.rs index 191c957c0..3661f86f2 100644 --- a/crates/extra/cgp-dispatch/src/providers/field_matchers/field_value.rs +++ b/crates/extra/cgp-dispatch/src/providers/field_matchers/field_value.rs @@ -1,6 +1,12 @@ use cgp::prelude::*; use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerComponent}; +/// The adapter that unwraps the tagged Field a matcher arm delivers and passes the bare payload to +/// an inner provider, so an ordinary computer can handle it. +/// +/// See +/// [`HandleFieldValue`](https://contextgeneric.dev/docs/reference/providers/dispatch/handle_field_value) +/// . pub struct HandleFieldValue(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/field_matchers/first_field_value.rs b/crates/extra/cgp-dispatch/src/providers/field_matchers/first_field_value.rs index 074fde06b..08c38b1cd 100644 --- a/crates/extra/cgp-dispatch/src/providers/field_matchers/first_field_value.rs +++ b/crates/extra/cgp-dispatch/src/providers/field_matchers/first_field_value.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerComponent}; +/// Handles the first field of a pair. pub struct HandleFirstFieldValue(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/matchers/match_first_with_field_handlers.rs b/crates/extra/cgp-dispatch/src/providers/matchers/match_first_with_field_handlers.rs index 51f12599b..1eec8b11e 100644 --- a/crates/extra/cgp-dispatch/src/providers/matchers/match_first_with_field_handlers.rs +++ b/crates/extra/cgp-dispatch/src/providers/matchers/match_first_with_field_handlers.rs @@ -9,21 +9,32 @@ use crate::{ MatchFirstWithHandlersRef, }; +/// The matcher for an (Input, Args) input: it matches the enum in the first element and passes the +/// extra arguments to every per-variant handler. +/// +/// See +/// [`MatchFirstWithFieldHandlers`](https://contextgeneric.dev/docs/reference/providers/dispatch/match_first_with_handlers) +/// . pub type MatchFirstWithFieldHandlers = UseInputDelegate>; +/// Matches the first field of a value with value handlers. pub type MatchFirstWithValueHandlers = UseInputDelegate>>; +/// Matches the first field of a borrowed value with field handlers. pub type MatchFirstWithFieldHandlersRef = UseInputDelegate>; +/// Matches the first field of a borrowed value with value handlers. pub type MatchFirstWithValueHandlersRef = UseInputDelegate>>; +/// Matches the first field of a mutably borrowed value with field handlers. pub type MatchFirstWithFieldHandlersMut = UseInputDelegate>; +/// Matches the first field of a mutably borrowed value with value handlers. pub type MatchFirstWithValueHandlersMut = UseInputDelegate>>; diff --git a/crates/extra/cgp-dispatch/src/providers/matchers/match_with_field_handlers.rs b/crates/extra/cgp-dispatch/src/providers/matchers/match_with_field_handlers.rs index 087f8afe6..2cef3c502 100644 --- a/crates/extra/cgp-dispatch/src/providers/matchers/match_with_field_handlers.rs +++ b/crates/extra/cgp-dispatch/src/providers/matchers/match_with_field_handlers.rs @@ -8,16 +8,31 @@ use cgp_handler::{ use crate::providers::matchers::to_field_handlers::{HasFieldHandlers, MapExtractFieldAndHandle}; use crate::{HandleFieldValue, MatchWithHandlers, MatchWithHandlersMut, MatchWithHandlersRef}; +/// The convenience matcher that builds the per-variant handler list from an enum's variants and +/// passes each payload as a Field tagged with its variant name. +/// +/// See +/// [`MatchWithFieldHandlers`](https://contextgeneric.dev/docs/reference/providers/dispatch/match_with_field_handlers) +/// . pub type MatchWithFieldHandlers = UseInputDelegate>; +/// The convenience matcher that builds the per-variant handler list from an enum's own variants and +/// passes each payload to one provider as a bare value. +/// +/// See +/// [`MatchWithValueHandlers`](https://contextgeneric.dev/docs/reference/providers/dispatch/match_with_value_handlers) +/// . pub type MatchWithValueHandlers = UseInputDelegate>>; +/// Matches a borrowed value with field handlers. pub struct MatchWithFieldHandlersRef(pub PhantomData); +/// Matches a borrowed value with value handlers. pub struct MatchWithValueHandlersRef(pub PhantomData); +/// Matches a mutably borrowed value with value handlers. pub struct MatchWithValueHandlersMut(pub PhantomData); delegate_components! { diff --git a/crates/extra/cgp-dispatch/src/providers/with_handlers/build_with_handlers.rs b/crates/extra/cgp-dispatch/src/providers/with_handlers/build_with_handlers.rs index 081aaae44..9f00e052b 100644 --- a/crates/extra/cgp-dispatch/src/providers/with_handlers/build_with_handlers.rs +++ b/crates/extra/cgp-dispatch/src/providers/with_handlers/build_with_handlers.rs @@ -4,6 +4,12 @@ use cgp_handler::{ TryComputerComponent, }; +/// The builder that starts an empty partial record, runs a list of steps that each fill fields, and +/// finalizes the record once every field is set. +/// +/// See +/// [`BuildWithHandlers`](https://contextgeneric.dev/docs/reference/providers/dispatch/build_with_handlers) +/// . pub struct BuildWithHandlers(pub PhantomData<(Output, Handlers)>); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers.rs b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers.rs index fe0680313..b43d64b6b 100644 --- a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers.rs +++ b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers.rs @@ -5,6 +5,12 @@ use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerCompo use crate::DispatchMatchers; +/// The matcher for an (Input, Args) input: it matches the enum in the first element and passes the +/// extra arguments to every per-variant handler. +/// +/// See +/// [`MatchFirstWithHandlers`](https://contextgeneric.dev/docs/reference/providers/dispatch/match_first_with_handlers) +/// . pub struct MatchFirstWithHandlers(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers_mut.rs b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers_mut.rs index 89f939881..316286932 100644 --- a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers_mut.rs +++ b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers_mut.rs @@ -5,6 +5,7 @@ use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerCompo use crate::DispatchMatchers; +/// Matches the first variant of a mutably borrowed value with handlers. pub struct MatchFirstWithHandlersMut(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers_ref.rs b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers_ref.rs index c1c2e330b..b1ffba565 100644 --- a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers_ref.rs +++ b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_first_with_handlers_ref.rs @@ -5,6 +5,7 @@ use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerCompo use crate::DispatchMatchers; +/// Matches the first variant of a borrowed value with handlers. pub struct MatchFirstWithHandlersRef(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers.rs b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers.rs index 75fecc443..f2ea03a56 100644 --- a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers.rs +++ b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers.rs @@ -6,6 +6,12 @@ use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerCompo use crate::DispatchMatchers; +/// The matcher that runs a spelled-out list of per-variant handlers over an enum, stopping at the +/// first match and needing no wildcard arm. +/// +/// See +/// [`MatchWithHandlers`](https://contextgeneric.dev/docs/reference/providers/dispatch/match_with_handlers) +/// . pub struct MatchWithHandlers(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers_mut.rs b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers_mut.rs index a0ef403b1..80b53d015 100644 --- a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers_mut.rs +++ b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers_mut.rs @@ -6,6 +6,7 @@ use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerCompo use crate::DispatchMatchers; +/// Matches a mutably borrowed value's variant with handlers. pub struct MatchWithHandlersMut(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers_ref.rs b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers_ref.rs index 5a98f62e8..382519d42 100644 --- a/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers_ref.rs +++ b/crates/extra/cgp-dispatch/src/providers/with_handlers/match_with_handlers_ref.rs @@ -6,6 +6,7 @@ use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerCompo use crate::DispatchMatchers; +/// Matches a borrowed value's variant with handlers. pub struct MatchWithHandlersRef(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-error-extra/src/impls/alloc/debug_error.rs b/crates/extra/cgp-error-extra/src/impls/alloc/debug_error.rs index 7cc36ab63..df180ffc4 100644 --- a/crates/extra/cgp-error-extra/src/impls/alloc/debug_error.rs +++ b/crates/extra/cgp-error-extra/src/impls/alloc/debug_error.rs @@ -5,6 +5,9 @@ use core::fmt::Debug; use cgp::error::{ErrorRaiser, ErrorRaiserComponent, ErrorWrapper, ErrorWrapperComponent}; use cgp::prelude::*; +/// Raises an error by formatting its source with `Debug`. +/// +/// See [`DebugError`](https://contextgeneric.dev/docs/reference/providers/error/debug_error). pub struct DebugError; #[cgp_provider] diff --git a/crates/extra/cgp-error-extra/src/impls/alloc/display_error.rs b/crates/extra/cgp-error-extra/src/impls/alloc/display_error.rs index e43b134a5..aa002795a 100644 --- a/crates/extra/cgp-error-extra/src/impls/alloc/display_error.rs +++ b/crates/extra/cgp-error-extra/src/impls/alloc/display_error.rs @@ -7,6 +7,9 @@ use cgp::error::{ }; use cgp::prelude::*; +/// Raises an error by formatting its source with `Display`. +/// +/// See [`DisplayError`](https://contextgeneric.dev/docs/reference/providers/error/display_error). pub struct DisplayError; #[cgp_provider] diff --git a/crates/extra/cgp-error-extra/src/lib.rs b/crates/extra/cgp-error-extra/src/lib.rs index 97868a236..1c05b4149 100644 --- a/crates/extra/cgp-error-extra/src/lib.rs +++ b/crates/extra/cgp-error-extra/src/lib.rs @@ -4,6 +4,7 @@ //! `alloc` feature. //! //! See [`RaiseFrom`](https://contextgeneric.dev/docs/reference/providers/error/raise_from), [`ReturnError`](https://contextgeneric.dev/docs/reference/providers/error/return_error), [`RaiseInfallible`](https://contextgeneric.dev/docs/reference/providers/error/raise_infallible), [`PanicOnError`](https://contextgeneric.dev/docs/reference/providers/error/panic_on_error), [`DiscardDetail`](https://contextgeneric.dev/docs/reference/providers/error/discard_detail), [`DebugError`](https://contextgeneric.dev/docs/reference/providers/error/debug_error), and [`DisplayError`](https://contextgeneric.dev/docs/reference/providers/error/display_error). +#![warn(missing_docs)] #[cfg(feature = "alloc")] extern crate alloc; diff --git a/crates/extra/cgp-field-extra/src/impls/build_default.rs b/crates/extra/cgp-field-extra/src/impls/build_default.rs index 20e3797ce..288fef1e5 100644 --- a/crates/extra/cgp-field-extra/src/impls/build_default.rs +++ b/crates/extra/cgp-field-extra/src/impls/build_default.rs @@ -1,13 +1,28 @@ use cgp_field::impls::{CanBuildFrom, IsNothing, IsOptional, IsPresent}; use cgp_field::traits::{FinalizeBuild, HasBuilder, TransformMap, TransformMapFields}; +/// Build a wider record from a narrower one in one call, copying the source's fields by name and +/// filling the rest from Default. +/// +/// See +/// [`CanBuildWithDefault`](https://contextgeneric.dev/docs/reference/traits/optional/can_build_with_default) +/// . pub trait CanBuildWithDefault { + /// Builds the value. fn build_with_default(source: Source) -> Self; } +/// End a build by filling every unset field from Default, for an optional builder or a core one, +/// then finalizing through the strict impl. +/// +/// See +/// [`CanFinalizeWithDefault`](https://contextgeneric.dev/docs/reference/traits/optional/can_finalize_with_default) +/// . pub trait CanFinalizeWithDefault { + /// The finalized value. type Output; + /// Finalizes the builder. fn finalize_with_default(self) -> Self::Output; } @@ -34,6 +49,12 @@ where } } +/// The transform marker behind the defaulting finalize: three per-field conversions that leave +/// every field present, filling gaps from Default. +/// +/// See +/// [`TransformMapDefault`](https://contextgeneric.dev/docs/reference/traits/optional/transform_map_default) +/// . pub struct TransformMapDefault; impl TransformMap for TransformMapDefault { diff --git a/crates/extra/cgp-field-extra/src/impls/finalize_optional.rs b/crates/extra/cgp-field-extra/src/impls/finalize_optional.rs index e09d1cdbc..e2e4d1c05 100644 --- a/crates/extra/cgp-field-extra/src/impls/finalize_optional.rs +++ b/crates/extra/cgp-field-extra/src/impls/finalize_optional.rs @@ -6,7 +6,14 @@ use cgp_field::traits::{ }; use cgp_field::types::{Cons, Field, Nil}; +/// End an optional build at run time: the concrete struct if every field holds a value, or the name +/// of a missing field as an Err. +/// +/// See +/// [`FinalizeOptional`](https://contextgeneric.dev/docs/reference/traits/optional/finalize_optional) +/// . pub trait FinalizeOptional: PartialData { + /// Finalizes the builder, or names the missing field. fn finalize_optional(self) -> Result; } diff --git a/crates/extra/cgp-field-extra/src/impls/set_optional.rs b/crates/extra/cgp-field-extra/src/impls/set_optional.rs index 7d65a244c..059a3c84b 100644 --- a/crates/extra/cgp-field-extra/src/impls/set_optional.rs +++ b/crates/extra/cgp-field-extra/src/impls/set_optional.rs @@ -3,11 +3,18 @@ use core::marker::PhantomData; use cgp_field::impls::IsOptional; use cgp_field::traits::UpdateField; +/// Set one field of an all-optional builder, as many times as you like, optionally getting back the +/// value it replaced. +/// +/// See [`SetOptional`](https://contextgeneric.dev/docs/reference/traits/optional/set_optional). pub trait SetOptional { + /// The field's value type. type Value; + /// Sets the field. fn set(self, _tag: PhantomData, value: Self::Value) -> Self; + /// Sets the field and returns the previous value. fn set_optional( self, _tag: PhantomData, diff --git a/crates/extra/cgp-field-extra/src/impls/to_optional.rs b/crates/extra/cgp-field-extra/src/impls/to_optional.rs index 6746e528f..8864faed0 100644 --- a/crates/extra/cgp-field-extra/src/impls/to_optional.rs +++ b/crates/extra/cgp-field-extra/src/impls/to_optional.rs @@ -1,9 +1,17 @@ use cgp_field::impls::{IsNothing, IsOptional, IsPresent}; use cgp_field::traits::{HasBuilder, TransformMap, TransformMapFields}; +/// Start a builder whose every field is an Option, set in any order and as often as you like, with +/// the choice of ending deferred to the finalize call. +/// +/// See +/// [`HasOptionalBuilder`](https://contextgeneric.dev/docs/reference/traits/optional/has_optional_builder) +/// . pub trait HasOptionalBuilder { + /// The optional builder type. type Builder; + /// Creates an empty optional builder. fn optional_builder() -> Self::Builder; } @@ -19,9 +27,15 @@ where } } +/// Re-mark every field of a core builder as optional, keeping set fields as Some, so the rest can +/// arrive in any order and the build can end either way. +/// +/// See [`ToOptional`](https://contextgeneric.dev/docs/reference/traits/optional/to_optional). pub trait ToOptional { + /// The optional builder. type Output; + /// Converts the builder. fn to_optional(self) -> Self::Output; } @@ -36,6 +50,12 @@ where } } +/// The transform marker behind ToOptional: two per-field conversions that wrap a present field in +/// Some and turn an absent one into None. +/// +/// See +/// [`TransformOptional`](https://contextgeneric.dev/docs/reference/traits/optional/transform_optional) +/// . pub struct TransformOptional; impl TransformMap for TransformOptional { diff --git a/crates/extra/cgp-field-extra/src/lib.rs b/crates/extra/cgp-field-extra/src/lib.rs index d7dd33457..dcf6604a5 100644 --- a/crates/extra/cgp-field-extra/src/lib.rs +++ b/crates/extra/cgp-field-extra/src/lib.rs @@ -2,5 +2,7 @@ //! This crate provides CGP's optional-field layer, for a builder whose fields are set in any order. //! //! See [`HasOptionalBuilder`](https://contextgeneric.dev/docs/reference/traits/optional/has_optional_builder), [`ToOptional`](https://contextgeneric.dev/docs/reference/traits/optional/to_optional), [`SetOptional`](https://contextgeneric.dev/docs/reference/traits/optional/set_optional), and [`FinalizeOptional`](https://contextgeneric.dev/docs/reference/traits/optional/finalize_optional). +#![warn(missing_docs)] +/// The optional-field traits' implementations. pub mod impls; diff --git a/crates/extra/cgp-handler/src/components/async_computer.rs b/crates/extra/cgp-handler/src/components/async_computer.rs index 71badf602..2634b078b 100644 --- a/crates/extra/cgp-handler/src/components/async_computer.rs +++ b/crates/extra/cgp-handler/src/components/async_computer.rs @@ -5,25 +5,41 @@ use cgp::prelude::*; use crate::UseInputDelegate; +/// The handler-family component for a computation that must await but cannot fail: its async method +/// returns the Output directly rather than a Result. +/// +/// See +/// [`CanComputeAsync`](https://contextgeneric.dev/docs/reference/components/handler/async_computer) +/// . #[async_trait] #[cgp_component(AsyncComputer)] #[prefix(@cgp.extra.handler in DefaultNamespace)] #[derive_delegate(UseDelegate)] #[derive_delegate(UseInputDelegate)] pub trait CanComputeAsync { + /// The transform's output. type Output; + /// Computes the output from the input. async fn compute_async(&self, _code: PhantomData, input: Input) -> Self::Output; } +/// The handler-family component for a computation that awaits, cannot fail, and only reads its +/// input, which its async method takes as &Input. +/// +/// See +/// [`CanComputeAsyncRef`](https://contextgeneric.dev/docs/reference/components/handler/async_computer_ref) +/// . #[async_trait] #[cgp_component(AsyncComputerRef)] #[prefix(@cgp.extra.handler in DefaultNamespace)] #[derive_delegate(UseDelegate)] #[derive_delegate(UseInputDelegate)] pub trait CanComputeAsyncRef { + /// The transform's output. type Output; + /// Computes the output from the borrowed input. async fn compute_async_ref(&self, _code: PhantomData, input: &Input) -> Self::Output; } diff --git a/crates/extra/cgp-handler/src/components/computer.rs b/crates/extra/cgp-handler/src/components/computer.rs index f533c9ff8..75c85c86d 100644 --- a/crates/extra/cgp-handler/src/components/computer.rs +++ b/crates/extra/cgp-handler/src/components/computer.rs @@ -5,23 +5,36 @@ use cgp::prelude::*; use crate::UseInputDelegate; +/// The handler-family component for a synchronous computation that cannot fail: a provider turns an +/// Input into an Output under a Code tag. +/// +/// See [`CanCompute`](https://contextgeneric.dev/docs/reference/components/handler/computer). #[cgp_component(Computer)] #[prefix(@cgp.extra.handler in DefaultNamespace)] #[derive_delegate(UseDelegate)] #[derive_delegate(UseInputDelegate)] pub trait CanCompute { + /// The transform's output. type Output; + /// Computes the output from the input. fn compute(&self, _code: PhantomData, input: Input) -> Self::Output; } +/// The handler-family component for a synchronous computation that cannot fail and only reads its +/// input, which it takes as &Input. +/// +/// See [`CanComputeRef`](https://contextgeneric.dev/docs/reference/components/handler/computer_ref) +/// . #[cgp_component(ComputerRef)] #[prefix(@cgp.extra.handler in DefaultNamespace)] #[derive_delegate(UseDelegate)] #[derive_delegate(UseInputDelegate)] pub trait CanComputeRef { + /// The transform's output. type Output; + /// Computes the output from the borrowed input. fn compute_ref(&self, _code: PhantomData, input: &Input) -> Self::Output; } diff --git a/crates/extra/cgp-handler/src/components/handler.rs b/crates/extra/cgp-handler/src/components/handler.rs index 7cc341f9a..88f9fa730 100644 --- a/crates/extra/cgp-handler/src/components/handler.rs +++ b/crates/extra/cgp-handler/src/components/handler.rs @@ -5,6 +5,10 @@ use cgp::prelude::*; use crate::UseInputDelegate; +/// The general handler-family component: an async computation that can fail, returning a Result in +/// the context's error type. Simpler members promote into it. +/// +/// See [`CanHandle`](https://contextgeneric.dev/docs/reference/components/handler/handler). #[async_trait] #[cgp_component(Handler)] #[prefix(@cgp.extra.handler in DefaultNamespace)] @@ -12,11 +16,17 @@ use crate::UseInputDelegate; #[derive_delegate(UseInputDelegate)] #[use_type(HasErrorType.Error)] pub trait CanHandle { + /// The handler's output. type Output; + /// Handles the input. async fn handle(&self, _tag: PhantomData, input: Input) -> Result; } +/// The handler-family component for an async computation that can fail and only reads its input, +/// which its async method takes as &Input. +/// +/// See [`CanHandleRef`](https://contextgeneric.dev/docs/reference/components/handler/handler_ref). #[async_trait] #[cgp_component(HandlerRef)] #[prefix(@cgp.extra.handler in DefaultNamespace)] @@ -24,8 +34,10 @@ pub trait CanHandle { #[derive_delegate(UseInputDelegate)] #[use_type(HasErrorType.Error)] pub trait CanHandleRef { + /// The handler's output. type Output; + /// Handles the borrowed input. async fn handle_ref( &self, _tag: PhantomData, diff --git a/crates/extra/cgp-handler/src/components/produce.rs b/crates/extra/cgp-handler/src/components/produce.rs index 1cf21536f..d5dc71727 100644 --- a/crates/extra/cgp-handler/src/components/produce.rs +++ b/crates/extra/cgp-handler/src/components/produce.rs @@ -3,11 +3,17 @@ use core::marker::PhantomData; use cgp::component::UseDelegate; use cgp::prelude::*; +/// The input-free handler-family component: a synchronous, infallible provider that produces an +/// Output from the context and a Code tag alone. +/// +/// See [`CanProduce`](https://contextgeneric.dev/docs/reference/components/handler/producer). #[cgp_component(Producer)] #[prefix(@cgp.extra.handler in DefaultNamespace)] #[derive_delegate(UseDelegate)] pub trait CanProduce { + /// The produced output. type Output; + /// Produces the output. fn produce(&self, _code: PhantomData) -> Self::Output; } diff --git a/crates/extra/cgp-handler/src/components/try_compute.rs b/crates/extra/cgp-handler/src/components/try_compute.rs index 9cc67e8e6..6e98c31a9 100644 --- a/crates/extra/cgp-handler/src/components/try_compute.rs +++ b/crates/extra/cgp-handler/src/components/try_compute.rs @@ -5,25 +5,40 @@ use cgp::prelude::*; use crate::UseInputDelegate; +/// The handler-family component for a synchronous computation that can fail, returning a Result in +/// the context's abstract error type. +/// +/// See [`CanTryCompute`](https://contextgeneric.dev/docs/reference/components/handler/try_computer) +/// . #[cgp_component(TryComputer)] #[prefix(@cgp.extra.handler in DefaultNamespace)] #[derive_delegate(UseDelegate)] #[derive_delegate(UseInputDelegate)] #[use_type(HasErrorType.Error)] pub trait CanTryCompute { + /// The transform's output. type Output; + /// Computes the output from the input. fn try_compute(&self, _code: PhantomData, input: Input) -> Result; } +/// The handler-family component for a synchronous computation that can fail and only reads its +/// input, returning a Result in the context's error type. +/// +/// See +/// [`CanTryComputeRef`](https://contextgeneric.dev/docs/reference/components/handler/try_computer_ref) +/// . #[cgp_component(TryComputerRef)] #[prefix(@cgp.extra.handler in DefaultNamespace)] #[derive_delegate(UseDelegate)] #[derive_delegate(UseInputDelegate)] #[use_type(HasErrorType.Error)] pub trait CanTryComputeRef { + /// The transform's output. type Output; + /// Computes the output from the borrowed input. fn try_compute_ref( &self, _code: PhantomData, diff --git a/crates/extra/cgp-handler/src/lib.rs b/crates/extra/cgp-handler/src/lib.rs index 873c98946..a0b364733 100644 --- a/crates/extra/cgp-handler/src/lib.rs +++ b/crates/extra/cgp-handler/src/lib.rs @@ -3,6 +3,7 @@ //! compose them. //! //! See [`CanCompute`](https://contextgeneric.dev/docs/reference/components/handler/computer), [`CanHandle`](https://contextgeneric.dev/docs/reference/components/handler/handler), [`PipeHandlers`](https://contextgeneric.dev/docs/reference/providers/handler/pipe_handlers), and [`Promote`](https://contextgeneric.dev/docs/reference/providers/handler/promote). +#![warn(missing_docs)] mod components; mod providers; diff --git a/crates/extra/cgp-handler/src/providers/compose.rs b/crates/extra/cgp-handler/src/providers/compose.rs index 262a1e4bd..626ad7dfb 100644 --- a/crates/extra/cgp-handler/src/providers/compose.rs +++ b/crates/extra/cgp-handler/src/providers/compose.rs @@ -5,6 +5,12 @@ use crate::{ TryComputer, TryComputerComponent, }; +/// The combinator that runs one handler and feeds its output to a second, as a Computer, +/// TryComputer, AsyncComputer, or Handler. +/// +/// See +/// [`ComposeHandlers`](https://contextgeneric.dev/docs/reference/providers/handler/compose_handlers) +/// . pub struct ComposeHandlers(pub PhantomData<(ProviderA, ProviderB)>); #[cgp_provider] diff --git a/crates/extra/cgp-handler/src/providers/pipe.rs b/crates/extra/cgp-handler/src/providers/pipe.rs index 7c9c4df47..dbe3aad27 100644 --- a/crates/extra/cgp-handler/src/providers/pipe.rs +++ b/crates/extra/cgp-handler/src/providers/pipe.rs @@ -4,6 +4,10 @@ use cgp::prelude::*; use crate::ComposeHandlers; +/// The combinator that folds a Product! list of handlers into nested ComposeHandlers, so the input +/// flows through each stage in turn. +/// +/// See [`PipeHandlers`](https://contextgeneric.dev/docs/reference/providers/handler/pipe_handlers). pub struct PipeHandlers(pub PhantomData); delegate_components! { diff --git a/crates/extra/cgp-handler/src/providers/promote.rs b/crates/extra/cgp-handler/src/providers/promote.rs index 46dd2ab4e..832d8e191 100644 --- a/crates/extra/cgp-handler/src/providers/promote.rs +++ b/crates/extra/cgp-handler/src/providers/promote.rs @@ -5,6 +5,10 @@ use crate::{ TryComputerComponent, }; +/// The single-step lift that turns a Producer into a Computer, a Computer into a TryComputer, and +/// an AsyncComputer into a Handler, adding no behavior. +/// +/// See [`Promote`](https://contextgeneric.dev/docs/reference/providers/handler/promote). pub struct Promote(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-handler/src/providers/promote_async.rs b/crates/extra/cgp-handler/src/providers/promote_async.rs index cbe2cfb79..f9eda06c4 100644 --- a/crates/extra/cgp-handler/src/providers/promote_async.rs +++ b/crates/extra/cgp-handler/src/providers/promote_async.rs @@ -4,6 +4,10 @@ use crate::{ AsyncComputer, AsyncComputerComponent, Computer, Handler, HandlerComponent, TryComputer, }; +/// The single-step lift that runs a synchronous Computer or TryComputer inside an async method, to +/// serve an AsyncComputer or Handler slot. +/// +/// See [`PromoteAsync`](https://contextgeneric.dev/docs/reference/providers/handler/promote_async). pub struct PromoteAsync(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-handler/src/providers/promote_ref.rs b/crates/extra/cgp-handler/src/providers/promote_ref.rs index 92e76ffb6..fab209206 100644 --- a/crates/extra/cgp-handler/src/providers/promote_ref.rs +++ b/crates/extra/cgp-handler/src/providers/promote_ref.rs @@ -9,6 +9,10 @@ use crate::{ TryComputerRefComponent, }; +/// The single-step lift between a handler family member and its …Ref companion: deref an owned +/// input for a …Ref provider, or pass a borrow as the input. +/// +/// See [`PromoteRef`](https://contextgeneric.dev/docs/reference/providers/handler/promote_ref). pub struct PromoteRef(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-handler/src/providers/return_input.rs b/crates/extra/cgp-handler/src/providers/return_input.rs index a7d542d72..7548a41fc 100644 --- a/crates/extra/cgp-handler/src/providers/return_input.rs +++ b/crates/extra/cgp-handler/src/providers/return_input.rs @@ -5,6 +5,10 @@ use crate::{ TryComputer, TryComputerComponent, }; +/// The handler that returns its input unchanged, the neutral stage of a pipeline, as a Computer, +/// TryComputer, AsyncComputer, or Handler. +/// +/// See [`ReturnInput`](https://contextgeneric.dev/docs/reference/providers/handler/return_input). pub struct ReturnInput; #[cgp_provider] diff --git a/crates/extra/cgp-handler/src/providers/try_promote.rs b/crates/extra/cgp-handler/src/providers/try_promote.rs index 39de548ac..7b07852e6 100644 --- a/crates/extra/cgp-handler/src/providers/try_promote.rs +++ b/crates/extra/cgp-handler/src/providers/try_promote.rs @@ -5,6 +5,10 @@ use crate::{ TryComputer, TryComputerComponent, }; +/// The single-step lift, in both directions, between a computer whose output is a Result and a +/// genuinely fallible TryComputer or Handler. +/// +/// See [`TryPromote`](https://contextgeneric.dev/docs/reference/providers/handler/try_promote). pub struct TryPromote(pub PhantomData); #[cgp_provider] diff --git a/crates/extra/cgp-handler/src/types.rs b/crates/extra/cgp-handler/src/types.rs index 7d478187f..1d9618542 100644 --- a/crates/extra/cgp-handler/src/types.rs +++ b/crates/extra/cgp-handler/src/types.rs @@ -1,6 +1,13 @@ use core::marker::PhantomData; +/// A code tag for a computation that takes no code. #[allow(non_upper_case_globals)] pub const NoCode: PhantomData<()> = PhantomData; +/// The legacy provider that routes a handler component to a per-input-type provider through a +/// nested table; the open statement replaces it. +/// +/// See +/// [`UseInputDelegate`](https://contextgeneric.dev/docs/reference/providers/handler/use_input_delegate) +/// . pub struct UseInputDelegate(pub PhantomData); diff --git a/crates/extra/cgp-monad/src/lib.rs b/crates/extra/cgp-monad/src/lib.rs index 4c77d7e38..207f072fa 100644 --- a/crates/extra/cgp-monad/src/lib.rs +++ b/crates/extra/cgp-monad/src/lib.rs @@ -2,7 +2,11 @@ //! This crate provides CGP's monadic handlers, which compose handlers through a monad. //! //! See [`MonadicBind`](https://contextgeneric.dev/docs/reference/traits/monad/monadic_bind), [`ContainsValue`](https://contextgeneric.dev/docs/reference/traits/monad/contains_value), [`LiftValue`](https://contextgeneric.dev/docs/reference/traits/monad/lift_value), and [`PipeMonadic`](https://contextgeneric.dev/docs/reference/providers/monad/pipe_monadic). +#![warn(missing_docs)] +/// The monads: identity, `Ok`, and `Err`. pub mod monadic; +/// The monadic providers, such as [`providers::PipeMonadic`]. pub mod providers; +/// The monad traits: bind, lift, transform, and value containment. pub mod traits; diff --git a/crates/extra/cgp-monad/src/monadic/err.rs b/crates/extra/cgp-monad/src/monadic/err.rs index 3beea7d53..9615e8fbe 100644 --- a/crates/extra/cgp-monad/src/monadic/err.rs +++ b/crates/extra/cgp-monad/src/monadic/err.rs @@ -4,8 +4,13 @@ use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerCompo use crate::monadic::ident::IdentMonadic; use crate::traits::{ContainsValue, LiftValue, MonadicBind, MonadicTrans}; +/// The per-step provider of the err monad: run the continuation on a step's Ok value and stop on +/// Err. PipeMonadic composes it under ErrMonadic. +/// +/// See [`BindErr`](https://contextgeneric.dev/docs/reference/providers/monad/bind_err). pub struct ErrMonadic; +/// The `Err` monad transformer. pub struct ErrMonadicTrans(pub PhantomData); impl MonadicTrans for ErrMonadic { @@ -29,6 +34,10 @@ where impl MonadicBind for ErrMonadic { type Provider = BindErr; } +/// The per-step provider of the err monad: run the continuation on a step's Ok value and stop on +/// Err. PipeMonadic composes it under ErrMonadic. +/// +/// See [`BindErr`](https://contextgeneric.dev/docs/reference/providers/monad/bind_err). pub struct BindErr(pub PhantomData<(M, Cont)>); impl ContainsValue> for ErrMonadic { diff --git a/crates/extra/cgp-monad/src/monadic/ident.rs b/crates/extra/cgp-monad/src/monadic/ident.rs index 0bedb5cf1..9310d2863 100644 --- a/crates/extra/cgp-monad/src/monadic/ident.rs +++ b/crates/extra/cgp-monad/src/monadic/ident.rs @@ -1,5 +1,6 @@ use crate::traits::{ContainsValue, LiftValue, MonadicBind, MonadicTrans}; +/// The identity monad. pub struct IdentMonadic; impl MonadicTrans for IdentMonadic { diff --git a/crates/extra/cgp-monad/src/monadic/mod.rs b/crates/extra/cgp-monad/src/monadic/mod.rs index 3903b1902..eb6c2661f 100644 --- a/crates/extra/cgp-monad/src/monadic/mod.rs +++ b/crates/extra/cgp-monad/src/monadic/mod.rs @@ -1,3 +1,6 @@ +/// The `Err` monad. pub mod err; +/// The identity monad. pub mod ident; +/// The `Ok` monad. pub mod ok; diff --git a/crates/extra/cgp-monad/src/monadic/ok.rs b/crates/extra/cgp-monad/src/monadic/ok.rs index d8bfdf4f1..d162939c5 100644 --- a/crates/extra/cgp-monad/src/monadic/ok.rs +++ b/crates/extra/cgp-monad/src/monadic/ok.rs @@ -4,10 +4,19 @@ use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerCompo use crate::monadic::ident::IdentMonadic; use crate::traits::{ContainsValue, LiftValue, MonadicBind, MonadicTrans}; +/// The per-step provider of the ok monad: run the continuation on a step's Err value and stop on +/// Ok. PipeMonadic composes it under OkMonadic. +/// +/// See [`BindOk`](https://contextgeneric.dev/docs/reference/providers/monad/bind_ok). pub struct OkMonadic; +/// The `Ok` monad transformer. pub struct OkMonadicTrans(pub PhantomData); +/// The per-step provider of the ok monad: run the continuation on a step's Err value and stop on +/// Ok. PipeMonadic composes it under OkMonadic. +/// +/// See [`BindOk`](https://contextgeneric.dev/docs/reference/providers/monad/bind_ok). pub struct BindOk(pub PhantomData<(M, Cont)>); impl MonadicTrans for OkMonadic { diff --git a/crates/extra/cgp-monad/src/providers/pipe_monadic.rs b/crates/extra/cgp-monad/src/providers/pipe_monadic.rs index eff049adb..33cef685d 100644 --- a/crates/extra/cgp-monad/src/providers/pipe_monadic.rs +++ b/crates/extra/cgp-monad/src/providers/pipe_monadic.rs @@ -8,6 +8,10 @@ use cgp_handler::{ use crate::monadic::err::ErrMonadic; use crate::traits::{MonadicBind, MonadicTrans}; +/// The provider that composes a Product! list of handlers under a monad marker, so each step runs +/// only on the previous step's continue case. +/// +/// See [`PipeMonadic`](https://contextgeneric.dev/docs/reference/providers/monad/pipe_monadic). pub struct PipeMonadic(pub PhantomData<(M, Providers)>); delegate_components! { @@ -38,6 +42,7 @@ delegate_components! { } } +/// Maps each provider to a [`TryPromote`] wrapper. pub struct TryPromoteProviders; impl MapType for TryPromoteProviders { diff --git a/crates/extra/cgp-monad/src/traits/bind.rs b/crates/extra/cgp-monad/src/traits/bind.rs index d5a401ca9..d9dd8ab17 100644 --- a/crates/extra/cgp-monad/src/traits/bind.rs +++ b/crates/extra/cgp-monad/src/traits/bind.rs @@ -1,3 +1,8 @@ +/// The monad trait that turns a continuation provider into the bind step running it, BindErr for +/// ErrMonadic and BindOk for OkMonadic. +/// +/// See [`MonadicBind`](https://contextgeneric.dev/docs/reference/traits/monad/monadic_bind). pub trait MonadicBind { + /// The bound provider. type Provider; } diff --git a/crates/extra/cgp-monad/src/traits/lift.rs b/crates/extra/cgp-monad/src/traits/lift.rs index f2f39d615..aa52e50df 100644 --- a/crates/extra/cgp-monad/src/traits/lift.rs +++ b/crates/extra/cgp-monad/src/traits/lift.rs @@ -1,7 +1,14 @@ +/// The monad trait that puts a value into a step's output on either branch: lift_value for a +/// short-circuit, lift_output for a continuation's result. +/// +/// See [`LiftValue`](https://contextgeneric.dev/docs/reference/traits/monad/lift_value). pub trait LiftValue { + /// The lifted output. type Output; + /// Lifts a value. fn lift_value(value: Value) -> Self::Output; + /// Lifts an output. fn lift_output(output: Output) -> Self::Output; } diff --git a/crates/extra/cgp-monad/src/traits/monadic_trans.rs b/crates/extra/cgp-monad/src/traits/monadic_trans.rs index 8194d0de0..93660b5be 100644 --- a/crates/extra/cgp-monad/src/traits/monadic_trans.rs +++ b/crates/extra/cgp-monad/src/traits/monadic_trans.rs @@ -1,3 +1,8 @@ +/// The monad trait applying one monad as a transformer over another, so a pipeline can peel a +/// nested Result; PipeMonadic uses it for fallible steps. +/// +/// See [`MonadicTrans`](https://contextgeneric.dev/docs/reference/traits/monad/monadic_trans). pub trait MonadicTrans { + /// The transformed monad. type M; } diff --git a/crates/extra/cgp-monad/src/traits/value.rs b/crates/extra/cgp-monad/src/traits/value.rs index dd897fb19..767328043 100644 --- a/crates/extra/cgp-monad/src/traits/value.rs +++ b/crates/extra/cgp-monad/src/traits/value.rs @@ -1,3 +1,8 @@ +/// The monad trait naming the value beneath a step's output that the monad threads forward: the Ok +/// payload under ErrMonadic, the error under OkMonadic. +/// +/// See [`ContainsValue`](https://contextgeneric.dev/docs/reference/traits/monad/contains_value). pub trait ContainsValue { + /// The contained value. type Value; } diff --git a/crates/extra/cgp-run/src/lib.rs b/crates/extra/cgp-run/src/lib.rs index 5d563b679..ca14c4f22 100644 --- a/crates/extra/cgp-run/src/lib.rs +++ b/crates/extra/cgp-run/src/lib.rs @@ -2,24 +2,35 @@ //! This crate provides CGP's task runners, which run a task named by a type-level code. //! //! See [`CanRun`](https://contextgeneric.dev/docs/reference/components/runner) and [`CanSendRun`](https://contextgeneric.dev/docs/reference/components/send_runner). +#![warn(missing_docs)] use core::future::Future; use core::marker::PhantomData; use cgp::prelude::*; +/// The async component that runs a task named at the type level to a Result, with each task code +/// dispatched to its own provider through wiring. +/// +/// See [`CanRun`](https://contextgeneric.dev/docs/reference/components/runner). #[cgp_component(Runner)] #[async_trait] #[derive_delegate(UseDelegate)] #[use_type(HasErrorType.Error)] pub trait CanRun { + /// Runs the task. async fn run(&self, _code: PhantomData) -> Result<(), Error>; } +/// The runner component whose future is Send, supplied by a proxy on the concrete context so a +/// spawning provider can hand work to a work-stealing executor. +/// +/// See [`CanSendRun`](https://contextgeneric.dev/docs/reference/components/send_runner). #[cgp_component(SendRunner)] #[async_trait] #[derive_delegate(UseDelegate)] #[use_type(HasErrorType.Error)] pub trait CanSendRun { + /// Runs the task and returns a `Send` future. fn send_run(&self, _code: PhantomData) -> impl Future> + Send; } diff --git a/crates/extra/cgp-runtime/src/lib.rs b/crates/extra/cgp-runtime/src/lib.rs index fff823c69..461bce7d5 100644 --- a/crates/extra/cgp-runtime/src/lib.rs +++ b/crates/extra/cgp-runtime/src/lib.rs @@ -2,6 +2,7 @@ //! //! See [`HasRuntime`](https://contextgeneric.dev/docs/reference/components/has_runtime) and [`HasRuntimeType`](https://contextgeneric.dev/docs/reference/components/has_runtime_type). #![no_std] +#![warn(missing_docs)] mod traits; diff --git a/crates/extra/cgp-runtime/src/traits/has_runtime.rs b/crates/extra/cgp-runtime/src/traits/has_runtime.rs index d20814084..000228a3b 100644 --- a/crates/extra/cgp-runtime/src/traits/has_runtime.rs +++ b/crates/extra/cgp-runtime/src/traits/has_runtime.rs @@ -2,8 +2,13 @@ use cgp::prelude::*; use crate::HasRuntimeType; +/// The getter component that borrows the runtime value a context stores, so effectful generic code +/// reaches Tokio, a mock, or a test executor generically. +/// +/// See [`HasRuntime`](https://contextgeneric.dev/docs/reference/components/has_runtime). #[cgp_getter] #[use_type(HasRuntimeType.Runtime)] pub trait HasRuntime { + /// Returns the context's runtime. fn runtime(&self) -> &Runtime; } diff --git a/crates/extra/cgp-runtime/src/traits/has_runtime_type.rs b/crates/extra/cgp-runtime/src/traits/has_runtime_type.rs index 446392a85..155a33246 100644 --- a/crates/extra/cgp-runtime/src/traits/has_runtime_type.rs +++ b/crates/extra/cgp-runtime/src/traits/has_runtime_type.rs @@ -1,8 +1,14 @@ use cgp::prelude::*; +/// The abstract-type component that declares the runtime type a context runs against, chosen by +/// wiring, for code that names the type but not a value. +/// +/// See [`HasRuntimeType`](https://contextgeneric.dev/docs/reference/components/has_runtime_type). #[cgp_type] pub trait HasRuntimeType { + /// The context's runtime type. type Runtime; } +/// The runtime type a context chooses. pub type RuntimeOf = ::Runtime; diff --git a/crates/macros/cgp-async-macro/src/lib.rs b/crates/macros/cgp-async-macro/src/lib.rs index 4f57818e4..8fe736210 100644 --- a/crates/macros/cgp-async-macro/src/lib.rs +++ b/crates/macros/cgp-async-macro/src/lib.rs @@ -3,6 +3,7 @@ //! `impl Future`. //! //! See [`#[async_trait]`](https://contextgeneric.dev/docs/reference/macros/async_trait). +#![warn(missing_docs)] extern crate alloc; extern crate proc_macro; diff --git a/crates/macros/cgp-macro-core/src/functions/camel_case.rs b/crates/macros/cgp-macro-core/src/functions/camel_case.rs index 302bab229..9016c800a 100644 --- a/crates/macros/cgp-macro-core/src/functions/camel_case.rs +++ b/crates/macros/cgp-macro-core/src/functions/camel_case.rs @@ -1,3 +1,4 @@ +/// Converts a snake-case name to PascalCase. pub fn to_camel_case_str(val: &str) -> String { val.split('_') .filter(|word| !word.is_empty()) diff --git a/crates/macros/cgp-macro-core/src/functions/field/parse.rs b/crates/macros/cgp-macro-core/src/functions/field/parse.rs index e70fa3e5c..1313ea2b3 100644 --- a/crates/macros/cgp-macro-core/src/functions/field/parse.rs +++ b/crates/macros/cgp-macro-core/src/functions/field/parse.rs @@ -231,6 +231,7 @@ fn try_parse_option_ref(type_path: &TypePath) -> Option<&TypeReference> { None } +/// Requires a type path to have exactly one segment and returns it. pub fn parse_single_segment_type_path(type_path: &TypePath) -> syn::Result<&PathSegment> { let [segment]: [&PathSegment; 1] = type_path .path diff --git a/crates/macros/cgp-macro-core/src/functions/generics/merge_generics.rs b/crates/macros/cgp-macro-core/src/functions/generics/merge_generics.rs index afa9df1ed..1aaf085a8 100644 --- a/crates/macros/cgp-macro-core/src/functions/generics/merge_generics.rs +++ b/crates/macros/cgp-macro-core/src/functions/generics/merge_generics.rs @@ -2,6 +2,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{Generics, WhereClause, WherePredicate}; +/// Merges two generic parameter lists and their `where` clauses. pub fn merge_generics(generics_a: &Generics, generics_b: &Generics) -> Generics { let mut params = generics_a.params.clone(); params.extend(generics_b.params.clone()); diff --git a/crates/macros/cgp-macro-core/src/functions/getter/parse.rs b/crates/macros/cgp-macro-core/src/functions/getter/parse.rs index 8aaf51273..5ad03a039 100644 --- a/crates/macros/cgp-macro-core/src/functions/getter/parse.rs +++ b/crates/macros/cgp-macro-core/src/functions/getter/parse.rs @@ -12,6 +12,7 @@ use crate::parse_internal; use crate::types::cgp_getter::{GetterField, ReceiverMode}; use crate::visitors::ReplaceSelfTypeVisitor; +/// Parses a getter trait's methods into fields and an optional associated type. pub fn parse_getter_fields( context_type: &Ident, consumer_trait: &ItemTrait, diff --git a/crates/macros/cgp-macro-core/src/functions/implicits/parse.rs b/crates/macros/cgp-macro-core/src/functions/implicits/parse.rs index b6b9ded1b..90e494566 100644 --- a/crates/macros/cgp-macro-core/src/functions/implicits/parse.rs +++ b/crates/macros/cgp-macro-core/src/functions/implicits/parse.rs @@ -8,6 +8,7 @@ use syn::{Attribute, FnArg, Meta, Pat, PatIdent, PatType, Receiver}; use crate::functions::parse_field_type_with; use crate::types::implicits::{ImplicitArgField, ImplicitArgFields}; +/// Extracts the `#[implicit]` arguments and parses them into fields. pub fn extract_and_parse_implicit_args( args: &mut Punctuated, ) -> syn::Result { @@ -49,6 +50,7 @@ pub fn extract_and_parse_implicit_args( Ok(ImplicitArgFields::new(implicit_args)) } +/// Parses one `#[implicit]` argument into a field. pub fn parse_implicit_arg(receiver: &Receiver, arg: &PatType) -> syn::Result { let Pat::Ident(pat_ident) = &*arg.pat else { return Err(syn::Error::new_spanned(&arg.pat, "Expected an identifier")); @@ -82,6 +84,7 @@ pub fn parse_implicit_arg(receiver: &Receiver, arg: &PatType) -> syn::Result) -> syn::Result> { let mut implicit_args = Vec::new(); @@ -102,6 +105,7 @@ pub fn extract_implicit_args(args: &mut Punctuated) -> syn::Result Ok(implicit_args) } +/// Returns whether an argument carries `#[implicit]`, rejecting a malformed form. pub fn is_implicit_arg(arg: &mut PatType) -> syn::Result { let mut res = false; @@ -128,6 +132,7 @@ pub fn is_implicit_arg(arg: &mut PatType) -> syn::Result { Ok(res) } +/// Returns whether an attribute is the bare `#[implicit]` marker. pub fn is_implicit_attr(attr: &Attribute) -> bool { match &attr.meta { Meta::Path(path) => path.is_ident("implicit"), @@ -135,6 +140,7 @@ pub fn is_implicit_attr(attr: &Attribute) -> bool { } } +/// Returns whether a pattern binds a mutable variable. pub fn has_mut_pattern(pat: &Pat) -> bool { let mut checker = MutChecker { has_mut: false }; checker.visit_pat(pat); diff --git a/crates/macros/cgp-macro-core/src/functions/snake_case.rs b/crates/macros/cgp-macro-core/src/functions/snake_case.rs index 19b2b3d7a..dbaf57995 100644 --- a/crates/macros/cgp-macro-core/src/functions/snake_case.rs +++ b/crates/macros/cgp-macro-core/src/functions/snake_case.rs @@ -1,6 +1,7 @@ use proc_macro2::Span; use syn::Ident; +/// Converts a PascalCase name to snake_case. pub fn to_snake_case_str(val: &str) -> String { let mut acc = String::new(); let mut prev = '_'; @@ -16,6 +17,7 @@ pub fn to_snake_case_str(val: &str) -> String { acc.to_lowercase() } +/// Converts an identifier to a reserved snake-case identifier. pub fn to_snake_case_ident(val: &Ident) -> Ident { let str_val = val.to_string(); let mut snake_case_val = to_snake_case_str(&str_val); diff --git a/crates/macros/cgp-macro-core/src/lib.rs b/crates/macros/cgp-macro-core/src/lib.rs index 7295e2765..884ff55ec 100644 --- a/crates/macros/cgp-macro-core/src/lib.rs +++ b/crates/macros/cgp-macro-core/src/lib.rs @@ -2,11 +2,19 @@ //! and code-generation helpers the macro crates build on. //! //! See [`#[cgp_component]`](https://contextgeneric.dev/docs/reference/macros/cgp_component) and [`#[cgp_impl]`](https://contextgeneric.dev/docs/reference/macros/cgp_impl) for the macros it builds. +#![warn(missing_docs)] +/// The re-exports the macro crates use. pub mod exports; +/// The shared parsing and code-generation helpers. pub mod functions; +/// The helper macros the AST types use. pub mod macros; +/// The shared traits the AST types implement. pub mod traits; +/// The AST types for the macros. pub mod types; +/// The vendored third-party helpers. pub mod vendor; +/// The visitors that rewrite the parsed items. pub mod visitors; diff --git a/crates/macros/cgp-macro-core/src/macros/export.rs b/crates/macros/cgp-macro-core/src/macros/export.rs index 02db7ff4c..86809e2e3 100644 --- a/crates/macros/cgp-macro-core/src/macros/export.rs +++ b/crates/macros/cgp-macro-core/src/macros/export.rs @@ -1,6 +1,8 @@ +/// Declares a marker struct that prints a `cgp` item's path when it is quoted. #[macro_export] macro_rules! export_construct { ( $from:ident => $to:ident ) => { + #[doc = concat!("A re-export of `", stringify!($to), "`.")] pub struct $from; impl ::quote::ToTokens for $from { @@ -14,6 +16,7 @@ macro_rules! export_construct { }; } +/// Declares several marker structs with [`export_construct!`]. #[macro_export] macro_rules! export_constructs { ( $( $from:ident $( => $to:ident )? ),* $(,)? ) => { diff --git a/crates/macros/cgp-macro-core/src/macros/keyword.rs b/crates/macros/cgp-macro-core/src/macros/keyword.rs index da0d5d862..c231de8ab 100644 --- a/crates/macros/cgp-macro-core/src/macros/keyword.rs +++ b/crates/macros/cgp-macro-core/src/macros/keyword.rs @@ -3,6 +3,7 @@ #[macro_export] macro_rules! define_keyword { ( $struct_ident:ident, $value:literal ) => { + #[doc = concat!("The `", $value, "` keyword marker.")] pub struct $struct_ident; impl $crate::traits::IsKeyword for $struct_ident { diff --git a/crates/macros/cgp-macro-core/src/traits/bounds.rs b/crates/macros/cgp-macro-core/src/traits/bounds.rs index 4f3d1882e..15d7b84b7 100644 --- a/crates/macros/cgp-macro-core/src/traits/bounds.rs +++ b/crates/macros/cgp-macro-core/src/traits/bounds.rs @@ -2,11 +2,15 @@ use syn::punctuated::Punctuated; use syn::token::Plus; use syn::{Generics, Type, TypeParamBound, parse_quote}; +/// Converts a value into a list of type-parameter bounds. pub trait ToTypeParamBounds { + /// The bounds the value represents. fn to_type_param_bounds(&self) -> syn::Result>; } +/// Adds a value's bounds to a `where` clause for a self type. pub trait AddTypeParamBounds { + /// Adds the bounds to the generics. fn add_type_param_bounds(&self, self_type: &Type, generics: &mut Generics) -> syn::Result<()>; } diff --git a/crates/macros/cgp-macro-core/src/traits/keyword.rs b/crates/macros/cgp-macro-core/src/traits/keyword.rs index c7d3ef6e7..cd8777346 100644 --- a/crates/macros/cgp-macro-core/src/traits/keyword.rs +++ b/crates/macros/cgp-macro-core/src/traits/keyword.rs @@ -3,11 +3,15 @@ use syn::parse::ParseBuffer; use crate::types::keyword::Keyword; +/// A marker for a keyword the macros parse. pub trait IsKeyword { + /// The keyword's spelling. const IDENT: &'static str; } +/// Peeks whether the next token is a keyword. pub trait PeekKeyword { + /// Returns whether the next token is the keyword. fn peek_keyword(&self) -> bool; } @@ -23,7 +27,9 @@ impl<'a> PeekKeyword for ParseBuffer<'a> { } } +/// Parses a keyword when it is present. pub trait ParseOptionalKeyword { + /// Parses the keyword, or returns `None`. fn parse_optional_keyword(&self) -> syn::Result>>; } diff --git a/crates/macros/cgp-macro-core/src/traits/to_type.rs b/crates/macros/cgp-macro-core/src/traits/to_type.rs index f11eb2a41..5f783aa33 100644 --- a/crates/macros/cgp-macro-core/src/traits/to_type.rs +++ b/crates/macros/cgp-macro-core/src/traits/to_type.rs @@ -1,5 +1,7 @@ use syn::Type; +/// Converts a value into a `syn::Type`. pub trait ToType { + /// The type the value represents. fn to_type(&self) -> Type; } diff --git a/crates/macros/cgp-macro-core/src/types/attributes/cgp_component_attributes.rs b/crates/macros/cgp-macro-core/src/types/attributes/cgp_component_attributes.rs index e429c991d..a065d7136 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/cgp_component_attributes.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/cgp_component_attributes.rs @@ -10,15 +10,21 @@ use crate::types::attributes::{ UseTypeAttributes, }; +/// The modifier attributes a `#[cgp_component]` trait carries. #[derive(Default, Clone)] pub struct CgpComponentAttributes { + /// The `#[extend]` supertraits. pub extend: Vec, + /// The `#[use_type]` imports. pub use_type: UseTypeAttributes, + /// The `#[prefix]` registrations. pub prefixes: Vec, + /// The `#[derive_delegate]` tables. pub derive_delegate_attributes: DeriveDelegateAttributes, } impl CgpComponentAttributes { + /// Parses the attributes and applies them to the trait. pub fn preprocess(item_trait: &ItemTrait) -> syn::Result<(Self, ItemTrait)> { let mut item_trait = item_trait.clone(); @@ -31,6 +37,7 @@ impl CgpComponentAttributes { Ok((attributes, item_trait)) } + /// Parses the trait's modifier attributes. pub fn parse(attributes: &mut Vec) -> syn::Result { let mut parsed_attributes = CgpComponentAttributes::default(); diff --git a/crates/macros/cgp-macro-core/src/types/attributes/cgp_impl_attributes.rs b/crates/macros/cgp-macro-core/src/types/attributes/cgp_impl_attributes.rs index 597c859a4..23fda4582 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/cgp_impl_attributes.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/cgp_impl_attributes.rs @@ -8,16 +8,23 @@ use crate::types::attributes::{ UseTypeAttribute, UseTypeAttributes, UsesAttributes, }; +/// The modifier attributes a `#[cgp_impl]` block carries. #[derive(Default)] pub struct CgpImplAttributes { + /// The `#[uses]` imports. pub uses: UsesAttributes, + /// The `#[use_type]` imports. pub use_type: UseTypeAttributes, + /// The `#[use_provider]` imports. pub use_provider: UseProviderAttributes, + /// The `#[default_impl]` registrations. pub default_impls: DefaultImplAttributes, + /// The attributes the macro passes through. pub raw_attributes: Vec, } impl CgpImplAttributes { + /// Parses the block's modifier attributes. pub fn parse(attributes: &Vec) -> syn::Result { let mut parsed_attributes = CgpImplAttributes::default(); diff --git a/crates/macros/cgp-macro-core/src/types/attributes/default_impl/attribute.rs b/crates/macros/cgp-macro-core/src/types/attributes/default_impl/attribute.rs index 1dba807d9..94657519c 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/default_impl/attribute.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/default_impl/attribute.rs @@ -8,13 +8,18 @@ use crate::parse_internal; use crate::types::ident::PathWithTypeArgs; use crate::types::path::UniPathOrType; +/// One `#[default_impl]` registration. pub struct DefaultImplAttribute { + /// The key the default is registered for. pub key_type: UniPathOrType, + /// The `in` keyword. pub in_token: In, + /// The namespace the default registers into. pub namespace: PathWithTypeArgs, } impl DefaultImplAttribute { + /// Emits the namespace impl that registers the default. pub fn to_item_impl( &self, provider_generics: &Generics, diff --git a/crates/macros/cgp-macro-core/src/types/attributes/default_impl/attributes.rs b/crates/macros/cgp-macro-core/src/types/attributes/default_impl/attributes.rs index 53a20d4ca..fd75ab36a 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/default_impl/attributes.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/default_impl/attributes.rs @@ -2,12 +2,15 @@ use syn::{Generics, ItemImpl, Type}; use crate::types::attributes::DefaultImplAttribute; +/// The `#[default_impl]` registrations of an impl block. #[derive(Default)] pub struct DefaultImplAttributes { + /// The registrations. pub attributes: Vec, } impl DefaultImplAttributes { + /// Emits the namespace impls for the registrations. pub fn to_item_impls( &self, provider_generics: &Generics, diff --git a/crates/macros/cgp-macro-core/src/types/attributes/derive_delegate/attribute.rs b/crates/macros/cgp-macro-core/src/types/attributes/derive_delegate/attribute.rs index 97a90d207..c0014b78a 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/derive_delegate/attribute.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/derive_delegate/attribute.rs @@ -7,13 +7,17 @@ use syn::{Error, Ident, ItemImpl, ItemTrait, Path, parenthesized}; use crate::exports::DelegateComponent; use crate::functions::{parse_internal, trait_items_to_delegated_impl_items}; +/// One `#[derive_delegate]` table. #[derive(Clone)] pub struct DeriveDelegateAttribute { + /// The wrapper provider's name. pub wrapper: Ident, + /// The dispatch parameters. pub params: Punctuated, } impl DeriveDelegateAttribute { + /// Emits the `UseDelegate` provider impl. pub fn to_provider_impl(&self, provider_trait: &ItemTrait) -> syn::Result { let provider_trait_ident = &provider_trait.ident; diff --git a/crates/macros/cgp-macro-core/src/types/attributes/derive_delegate/attributes.rs b/crates/macros/cgp-macro-core/src/types/attributes/derive_delegate/attributes.rs index d4bf6908f..0ec39a6a4 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/derive_delegate/attributes.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/derive_delegate/attributes.rs @@ -1,6 +1,8 @@ use crate::types::attributes::DeriveDelegateAttribute; +/// The `#[derive_delegate]` tables of a component. #[derive(Default, Clone)] pub struct DeriveDelegateAttributes { + /// The tables. pub attributes: Vec, } diff --git a/crates/macros/cgp-macro-core/src/types/attributes/function.rs b/crates/macros/cgp-macro-core/src/types/attributes/function.rs index 75e375bf7..5cead640d 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/function.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/function.rs @@ -6,18 +6,27 @@ use crate::types::attributes::{ UseProviderAttribute, UseProviderAttributes, UseTypeAttribute, UseTypeAttributes, }; +/// The modifier attributes a `#[cgp_fn]` or `#[cgp_impl]` function carries. #[derive(Default)] pub struct FunctionAttributes { + /// The `#[extend]` supertraits. pub extend: Vec, + /// The `#[extend_where]` predicates. pub extend_where: Vec, + /// The `#[uses]` trait bounds. pub uses: Vec, + /// The `#[use_type]` imports. pub use_type: UseTypeAttributes, + /// The `#[use_provider]` imports. pub use_provider: UseProviderAttributes, + /// The `#[impl_generics]` parameters. pub impl_generics: Vec, + /// The attributes the macro passes through. pub raw_attributes: Vec, } impl FunctionAttributes { + /// Parses the function's modifier attributes. pub fn parse(attributes: Vec) -> syn::Result { let mut parsed_attributes = FunctionAttributes::default(); diff --git a/crates/macros/cgp-macro-core/src/types/attributes/prefix.rs b/crates/macros/cgp-macro-core/src/types/attributes/prefix.rs index d699b897d..8bdb4a2c9 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/prefix.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/prefix.rs @@ -7,14 +7,19 @@ use crate::functions::parse_internal; use crate::types::ident::{IdentWithTypeGenerics, PathWithTypeArgs}; use crate::types::path::UniPath; +/// One `#[prefix]` registration. #[derive(Clone)] pub struct PrefixAttribute { + /// The path the component registers under. pub path: UniPath, + /// The `in` keyword. pub _in_token: In, + /// The namespace the component registers into. pub namespace: PathWithTypeArgs, } impl PrefixAttribute { + /// Emits the namespace impl that redirects the component's lookup. pub fn to_namespace_impl( &self, component_name: &IdentWithTypeGenerics, diff --git a/crates/macros/cgp-macro-core/src/types/attributes/use_provider/attribute.rs b/crates/macros/cgp-macro-core/src/types/attributes/use_provider/attribute.rs index c7229d443..704ee25b7 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/use_provider/attribute.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/use_provider/attribute.rs @@ -6,14 +6,20 @@ use syn::{Type, TypeParamBound, WherePredicate}; use crate::parse_internal; use crate::types::ident::PathWithTypeArgs; +/// One `#[use_provider]` import. pub struct UseProviderAttribute { + /// The context type. pub context_type: Type, + /// The provider type. pub provider_type: Type, + /// The colon between the provider and its bounds. pub colon: Colon, + /// The provider trait bounds. pub provider_trait_bounds: Punctuated, } impl UseProviderAttribute { + /// Builds the bounds with the context as the leading argument. pub fn to_type_param_bounds( &self, context_type: &Type, @@ -38,6 +44,7 @@ impl UseProviderAttribute { Ok(bounds) } + /// Builds the `where` predicate for the provider. pub fn to_provider_bounds(&self, context_type: &Type) -> syn::Result { let provider_type = &self.provider_type; let bounds = self.to_type_param_bounds(context_type)?; diff --git a/crates/macros/cgp-macro-core/src/types/attributes/use_provider/attributes.rs b/crates/macros/cgp-macro-core/src/types/attributes/use_provider/attributes.rs index dc4ae5543..23654409e 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/use_provider/attributes.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/use_provider/attributes.rs @@ -3,8 +3,10 @@ use syn::{Generics, Type}; use crate::traits::AddTypeParamBounds; use crate::types::attributes::UseProviderAttribute; +/// The `#[use_provider]` imports of a function or impl block. #[derive(Default)] pub struct UseProviderAttributes { + /// The imports. pub attributes: Vec, } diff --git a/crates/macros/cgp-macro-core/src/types/attributes/use_type/attribute.rs b/crates/macros/cgp-macro-core/src/types/attributes/use_type/attribute.rs index 1496bd739..b2998b198 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/use_type/attribute.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/use_type/attribute.rs @@ -11,8 +11,11 @@ use crate::types::ident::{PathWithTypeArgs, TypeArg}; /// type set by a trailing `in Context`). #[derive(Clone)] pub struct UseTypeAttribute { + /// The context the types are projected against. pub context_type: Type, + /// The owning trait's path. pub trait_path: PathWithTypeArgs, + /// The imported associated types. pub type_idents: Vec, } @@ -26,6 +29,7 @@ impl UseTypeAttribute { /// nothing. Naming the set once — rather than at each of the three places that /// walk it — is what keeps the grounding pass, the emitted bounds, and the /// cycle check in agreement about what grounding reaches. + /// The type positions grounding resolves. pub fn groundable_types(&self) -> impl Iterator { core::iter::once(&self.context_type).chain( self.trait_path @@ -41,6 +45,7 @@ impl UseTypeAttribute { } /// [`Self::groundable_types`] by mutable reference, for the grounding pass. + /// The type positions grounding resolves, mutably. pub fn groundable_types_mut(&mut self) -> impl Iterator { core::iter::once(&mut self.context_type).chain( self.trait_path @@ -54,6 +59,7 @@ impl UseTypeAttribute { ) } + /// Resolves an alias to the type it imports. pub fn replace_ident(&self, ident: &Ident) -> Option { for type_ident in &self.type_idents { if type_ident.alias_ident() == ident { diff --git a/crates/macros/cgp-macro-core/src/types/attributes/use_type/attributes.rs b/crates/macros/cgp-macro-core/src/types/attributes/use_type/attributes.rs index 2b9b64166..450daacc2 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/use_type/attributes.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/use_type/attributes.rs @@ -10,8 +10,10 @@ use crate::types::attributes::use_type::type_predicates::{ }; use crate::visitors::SubstituteAbstractTypes; +/// The `#[use_type]` imports of a function or impl block. #[derive(Default, Clone)] pub struct UseTypeAttributes { + /// The imports. pub attributes: Vec, } @@ -28,6 +30,7 @@ impl UseTypeAttributes { ground_specs(&self.attributes) } + /// Substitutes the imports in a trait and adds their bounds. pub fn transform_item_trait(&self, item_trait: &mut ItemTrait) -> syn::Result<()> { if self.attributes.is_empty() { return Ok(()); @@ -71,6 +74,7 @@ impl UseTypeAttributes { Ok(()) } + /// Substitutes the imports in an impl and adds their bounds. pub fn transform_item_impl(&self, item_impl: &mut ItemImpl) -> syn::Result<()> { if self.attributes.is_empty() { return Ok(()); diff --git a/crates/macros/cgp-macro-core/src/types/attributes/use_type/ident.rs b/crates/macros/cgp-macro-core/src/types/attributes/use_type/ident.rs index 798cc8cb1..de8020ca9 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/use_type/ident.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/use_type/ident.rs @@ -2,14 +2,19 @@ use syn::parse::{Parse, ParseStream}; use syn::token::{As, Eq}; use syn::{Ident, Type}; +/// One imported abstract type, with its optional alias and equality. #[derive(Clone)] pub struct UseTypeIdent { + /// The type's name. pub type_ident: Ident, + /// The `as` alias, when given. pub as_alias: Option, + /// The `= Type` equality, when given. pub equals: Option, } impl UseTypeIdent { + /// The name the type is written as. pub fn alias_ident(&self) -> &Ident { self.as_alias.as_ref().unwrap_or(&self.type_ident) } diff --git a/crates/macros/cgp-macro-core/src/types/attributes/uses.rs b/crates/macros/cgp-macro-core/src/types/attributes/uses.rs index 0ba9852a3..f2afc9171 100644 --- a/crates/macros/cgp-macro-core/src/types/attributes/uses.rs +++ b/crates/macros/cgp-macro-core/src/types/attributes/uses.rs @@ -10,6 +10,7 @@ use crate::traits::ToTypeParamBounds; /// is accepted in addition to the plain `Trait` form. #[derive(Default)] pub struct UsesAttributes { + /// The imported bounds. pub imports: Vec, } diff --git a/crates/macros/cgp-macro-core/src/types/blanket_trait.rs b/crates/macros/cgp-macro-core/src/types/blanket_trait.rs index 8cab3dc2b..a79df5220 100644 --- a/crates/macros/cgp-macro-core/src/types/blanket_trait.rs +++ b/crates/macros/cgp-macro-core/src/types/blanket_trait.rs @@ -7,12 +7,16 @@ use syn::{ use crate::parse_internal; use crate::visitors::RemoveSelfPathVisitor; +/// The parsed `#[blanket_trait]` input. pub struct ItemBlanketTrait { + /// The context parameter's name. pub context_ident: Ident, + /// The annotated trait. pub item_trait: ItemTrait, } impl ItemBlanketTrait { + /// Emits the trait and its blanket impl. pub fn to_items(&self) -> syn::Result> { let item_trait = self.item_trait.clone(); let item_impl = self.to_item_impl()?; @@ -20,6 +24,7 @@ impl ItemBlanketTrait { Ok(vec![item_trait.into(), item_impl.into()]) } + /// Emits the blanket impl from the trait's default bodies. pub fn to_item_impl(&self) -> syn::Result { let context_ident = &self.context_ident; let mut item_trait = self.item_trait.clone(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_auto_getter/blanket.rs b/crates/macros/cgp-macro-core/src/types/cgp_auto_getter/blanket.rs index 1f0078eff..d0484330d 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_auto_getter/blanket.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_auto_getter/blanket.rs @@ -7,6 +7,7 @@ use crate::types::field::{FieldName, HasFieldBound}; use crate::types::getter::{ContextArg, derive_getter_method}; use crate::visitors::get_bounds_and_replace_self_assoc_type; +/// Derives the blanket impl over `HasField` for a getter trait. pub fn derive_blanket_impl( context_type: &Ident, consumer_trait: &ItemTrait, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_auto_getter/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_auto_getter/item.rs index e2b7c8959..86469d1ed 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_auto_getter/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_auto_getter/item.rs @@ -5,16 +5,20 @@ use crate::functions::parse_getter_fields; use crate::types::attributes::CgpComponentAttributes; use crate::types::cgp_auto_getter::derive_blanket_impl; +/// The parsed `#[cgp_auto_getter]` input. pub struct ItemCgpAutoGetter { + /// The annotated trait. pub item_trait: ItemTrait, } impl ItemCgpAutoGetter { + /// Parses the trait's attributes. pub fn preprocess(item_trait: &ItemTrait) -> syn::Result { let (_attributes, item_trait) = CgpComponentAttributes::preprocess(item_trait)?; Ok(Self { item_trait }) } + /// Emits the trait and its blanket impl. pub fn to_items(&self) -> syn::Result> { let item_trait = self.item_trait.clone().into(); let item_impl = self.to_blanket_impl()?.into(); @@ -22,6 +26,7 @@ impl ItemCgpAutoGetter { Ok(vec![item_trait, item_impl]) } + /// Emits the blanket impl over `HasField`. pub fn to_blanket_impl(&self) -> syn::Result { let context_type = Ident::new("__Context__", Span::call_site()); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_component/args/component_args.rs b/crates/macros/cgp-macro-core/src/types/cgp_component/args/component_args.rs index d29e8242c..209d94b82 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_component/args/component_args.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_component/args/component_args.rs @@ -10,8 +10,11 @@ use crate::types::ident::IdentWithTypeGenerics; /// the component marker name (`{Provider}Component` by default). #[derive(Clone)] pub struct CgpComponentArgs { + /// The context identifier. pub context_ident: Ident, + /// The provider trait's name. pub provider_ident: Ident, + /// The component marker's name. pub component_name: IdentWithTypeGenerics, } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_component/args/raw.rs b/crates/macros/cgp-macro-core/src/types/cgp_component/args/raw.rs index b2260f18a..14149ad18 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_component/args/raw.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_component/args/raw.rs @@ -9,8 +9,11 @@ use crate::types::ident::IdentWithTypeGenerics; /// resolves the defaults via `TryFrom`. #[derive(Default)] pub struct CgpComponentRawArgs { + /// The context identifier, when given. pub context_ident: Option, + /// The provider trait's name, when given. pub provider_ident: Option, + /// The component marker's name, when given. pub component_name: Option, } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_component/evaluated/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_component/evaluated/item.rs index bc20d02da..4b014ddd6 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_component/evaluated/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_component/evaluated/item.rs @@ -9,18 +9,26 @@ use crate::types::provider_impl::{ItemProviderImpl, ItemProviderImpls}; /// to render the standard provider impls (`UseContext`, `RedirectLookup`, and the /// per-attribute `UseDelegate`/prefix impls). pub struct EvaluatedCgpComponent { + /// The component marker struct. pub component_struct: EmptyStruct, + /// The consumer trait. pub consumer_trait: ItemTrait, + /// The consumer trait's blanket impl. pub consumer_impl: ItemImpl, + /// The provider trait. pub provider_trait: ItemTrait, + /// The provider trait's blanket impl. pub provider_impl: ItemImpl, + /// The component's arguments. pub args: CgpComponentArgs, + /// The component's attributes. pub attributes: CgpComponentAttributes, } impl EvaluatedCgpComponent { /// Emit the five core items in fixed order (consumer trait, consumer impl, /// provider trait, provider impl, marker struct), then the provider impls. + /// Emits the component's items. pub fn to_items(&self) -> syn::Result> { let mut items = vec![ Item::Trait(self.consumer_trait.clone()), @@ -39,6 +47,7 @@ impl EvaluatedCgpComponent { /// The standard provider impls (`UseContext`, `RedirectLookup`, per-attribute /// `UseDelegate`) followed by one namespace prefix impl per `#[prefix]`. + /// Emits the component's provider impls. pub fn to_item_impls(&self) -> syn::Result> { let mut item_impls = self.to_provider_impls()?.to_item_impls()?; @@ -49,6 +58,7 @@ impl EvaluatedCgpComponent { /// The `UseContext` and `RedirectLookup` impls always emitted for a component, /// plus one `UseDelegate` impl per `#[derive_delegate]` attribute. + /// Emits the standard provider impls. pub fn to_provider_impls(&self) -> syn::Result { let mut provider_impls = ItemProviderImpls::default(); @@ -65,6 +75,7 @@ impl EvaluatedCgpComponent { } /// One `UseDelegate` provider impl per `#[derive_delegate]` attribute. + /// Emits one `UseDelegate` impl per `#[derive_delegate]`. pub fn to_use_delegate_impls(&self) -> syn::Result { let provider_trait = &self.provider_trait; let component_type = self.args.component_name.to_type(); @@ -82,6 +93,7 @@ impl EvaluatedCgpComponent { } /// One namespace prefix impl per `#[prefix]` attribute (from `#[cgp_namespace]`). + /// Emits one namespace prefix impl per `#[prefix]`. pub fn to_prefix_impls(&self) -> syn::Result> { let component_name = &self.args.component_name; let mut provider_impls = Vec::new(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_component/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_component/item.rs index fdfc80714..4619443ac 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_component/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_component/item.rs @@ -7,12 +7,15 @@ use crate::types::ident::TypeGenericParam; /// Raw input stage: the parsed attribute args and trait, before CGP attributes /// are stripped. First stage of the `#[cgp_component]` pipeline. pub struct ItemCgpComponent { + /// The component's arguments. pub args: CgpComponentArgs, + /// The annotated trait. pub item_trait: ItemTrait, } impl ItemCgpComponent { /// Split the CGP modifier attributes off the trait, yielding the next stage. + /// Splits the modifier attributes off the trait. pub fn preprocess(&self) -> syn::Result { self.check_component_name_params()?; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_component/preprocessed/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_component/preprocessed/item.rs index f665f1eb1..f9886b113 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_component/preprocessed/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_component/preprocessed/item.rs @@ -8,13 +8,17 @@ use crate::types::empty_struct::EmptyStruct; /// attributes, carrying the methods that derive the provider trait, the blanket /// impls, and the component marker. pub struct PreprocessedCgpComponent { + /// The component's arguments. pub args: CgpComponentArgs, + /// The annotated trait. pub item_trait: ItemTrait, + /// The trait's modifier attributes. pub attributes: CgpComponentAttributes, } impl PreprocessedCgpComponent { /// Build the zero-sized `{Provider}Component` marker struct. + /// Builds the component marker struct. pub fn to_component_struct(&self) -> EmptyStruct { let component_name = &self.args.component_name; let consumer_trait = &self.item_trait.ident; @@ -27,6 +31,7 @@ impl PreprocessedCgpComponent { /// Derive the marker struct, provider trait, and both blanket impls, yielding /// the final stage. + /// Derives the component's items. pub fn eval(&self) -> syn::Result { let component_struct = self.to_component_struct(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs index 20debb057..3b36506fe 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs @@ -4,6 +4,7 @@ use crate::exports::MapType; use crate::parse_internal; use crate::types::cgp_data::{index_to_generic_ident, retain_companion_attrs}; +/// Derives the builder struct for a record. pub fn derive_builder_struct( context_struct: &ItemStruct, builder_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs index 5ac35e2bc..badac1750 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs @@ -8,6 +8,7 @@ use crate::functions::override_item_span; use crate::parse_internal; use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; +/// Derives the `FinalizeBuild` impl for a builder. pub fn derive_finalize_build_impl( context_struct: &ItemStruct, builder_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs index 24af85c7f..08632d712 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs @@ -8,6 +8,7 @@ use crate::functions::override_item_span; use crate::parse_internal; use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; +/// Derives the `HasBuilder` impl for a struct. pub fn derive_has_builder_impl( context_struct: &ItemStruct, builder_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs index 5b91fbb25..c13f03337 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs @@ -8,6 +8,7 @@ use crate::types::cgp_data::{ field_to_member, field_to_tag, index_to_generic_ident, to_generic_args, }; +/// Derives the `HasField` impls for a builder. pub fn derive_has_field_impls( context_struct: &ItemStruct, builder_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs index 7b2b6c581..6376cf157 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs @@ -8,6 +8,7 @@ use crate::functions::override_item_span; use crate::parse_internal; use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; +/// Derives the `IntoBuilder` impl for a struct. pub fn derive_into_builder_impl( context_struct: &ItemStruct, builder_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs index ae6557d16..d8ff6fc18 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs @@ -5,6 +5,7 @@ use crate::functions::override_item_span; use crate::parse_internal; use crate::types::cgp_data::index_to_generic_ident; +/// Derives the `PartialData` impl for a builder. pub fn derive_partial_data_impl_from_struct( context_struct: &ItemStruct, builder_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs index f30cdd167..28fd952c6 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs @@ -11,6 +11,7 @@ use crate::types::cgp_data::{ field_to_member, field_to_tag, field_value_expr, index_to_generic_ident, to_generic_args, }; +/// Derives the `UpdateField` impls for a builder. pub fn derive_update_field_impls( context_struct: &ItemStruct, builder_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/utils.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/utils.rs index 6b223194b..1ee880a35 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/utils.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/utils.rs @@ -7,6 +7,7 @@ use syn::{AngleBracketedGenericArguments, Field, FieldValue, Generics, Ident, Me use crate::functions::parse_internal; use crate::types::field::{FieldName, Index, Symbol}; +/// Renders a generic list as angle-bracketed arguments. pub fn to_generic_args(generics: &Generics) -> syn::Result { if generics.params.is_empty() { parse2(quote! { < > }) @@ -15,6 +16,7 @@ pub fn to_generic_args(generics: &Generics) -> syn::Result Member { match &field.ident { Some(ident) => Member::Named(ident.clone()), @@ -22,6 +24,7 @@ pub fn field_to_member(index: usize, field: &Field) -> Member { } } +/// The type-level tag a field is named by. pub fn field_to_tag(index: usize, field: &Field) -> FieldName { match &field.ident { Some(ident) => FieldName::Ident(Symbol::from_ident(ident.clone())), @@ -32,10 +35,12 @@ pub fn field_to_tag(index: usize, field: &Field) -> FieldName { } } +/// The generic identifier for a field's index. pub fn index_to_generic_ident(index: usize) -> Ident { Ident::new(&format!("__F{index}__"), Span::call_site()) } +/// Builds a field-value expression. pub fn field_value_expr(field_member: Member, expr: TokenStream) -> syn::Result { Ok(FieldValue { attrs: Vec::new(), diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs index 52273945d..7c76a643f 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs @@ -6,6 +6,7 @@ use crate::functions::override_item_span; use crate::parse_internal; use crate::types::field::{Index, Symbol}; +/// Derives the `HasField` impls for a struct. pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> syn::Result> { let struct_ident = &item_struct.ident; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs index e44845e34..69ba34a72 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs @@ -10,6 +10,7 @@ use crate::types::cgp_data::{ variants_to_sum_type, }; +/// Derives the `HasFields` impls for an enum. pub fn derive_has_fields_impls_from_enum(item_enum: &ItemEnum) -> syn::Result> { let struct_name = &item_enum.ident; let (impl_generics, type_generics, where_clause) = item_enum.generics.split_for_impl(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs index 39eeb51b4..c9831aea8 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs @@ -10,6 +10,7 @@ use crate::types::cgp_data::{ item_fields_to_product_type, }; +/// Derives the `HasFields` impls for a struct. pub fn derive_has_fields_impls_from_struct(item_struct: &ItemStruct) -> syn::Result> { let struct_name = &item_struct.ident; let (impl_generics, type_generics, where_clause) = item_struct.generics.split_for_impl(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs index 5653632b4..455c6d336 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs @@ -5,6 +5,7 @@ use crate::exports::{Either, FromFields, HasFields}; use crate::functions::parse_internal; use crate::types::cgp_data::derive_from_field_params; +/// Derives the `FromFields` impl for an enum. pub fn derive_from_fields_for_enum(item_enum: &ItemEnum) -> syn::Result { let enum_name = &item_enum.ident; let (impl_generics, type_generics, where_clause) = item_enum.generics.split_for_impl(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs index 9d77a9bb1..21ae85cb0 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs @@ -6,6 +6,7 @@ use syn::{Error, Fields, Ident, ItemImpl, ItemStruct}; use crate::exports::{Cons, FromFields, Nil}; use crate::parse_internal; +/// Derives the `FromFields` impl for a struct. pub fn derive_from_fields_for_struct(item_struct: &ItemStruct) -> syn::Result { let struct_name = &item_struct.ident; let (impl_generics, type_generics, where_clause) = item_struct.generics.split_for_impl(); @@ -28,6 +29,7 @@ pub fn derive_from_fields_for_struct(item_struct: &ItemStruct) -> syn::Result syn::Result<(TokenStream, TokenStream)> { match fields { Fields::Named(fields) => { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs index e14f2e0f1..1a194c966 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs @@ -7,6 +7,7 @@ use crate::exports::{Cons, Field, Index, Nil}; use crate::functions::parse_internal; use crate::types::field::Symbol; +/// Builds the `Product!` type of a struct's fields. pub fn item_fields_to_product_type(fields: &Fields, reference: &TokenStream) -> syn::Result { let mut fields_type = quote! { #Nil }; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs index b6f6f6d43..8ec0ff672 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs @@ -9,6 +9,7 @@ use crate::functions::parse_internal; use crate::types::cgp_data::item_fields_to_product_type; use crate::types::field::Symbol; +/// Builds the `Sum!` type of an enum's variants. pub fn variants_to_sum_type( variants: &Punctuated, reference: &TokenStream, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs index 26f26a8b1..2642a9aac 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs @@ -9,6 +9,7 @@ use crate::exports::{Either, HasFields, ToFields}; use crate::functions::parse_internal; use crate::types::cgp_data::{FieldLabel, derive_to_fields_constructor}; +/// Derives the `ToFields` impl for an enum. pub fn derive_to_fields_for_enum(item_enum: &ItemEnum) -> syn::Result { let enum_name = &item_enum.ident; let (impl_generics, type_generics, where_clause) = item_enum.generics.split_for_impl(); @@ -33,6 +34,7 @@ pub fn derive_to_fields_for_enum(item_enum: &ItemEnum) -> syn::Result parse_internal(item_impl) } +/// Builds the match arms that turn each variant into its field list. pub fn derive_to_fields_match_arms( variants: &Punctuated, ) -> syn::Result { @@ -82,6 +84,7 @@ pub fn derive_to_fields_match_arms( Ok(match_arms) } +/// Builds the pattern that binds a variant's fields. pub fn extract_variant_args(fields: &Fields) -> syn::Result { match fields { Fields::Named(fields) => { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs index 3b63de157..bb38741b8 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs @@ -5,6 +5,7 @@ use crate::exports::{HasFieldsRef, ToFieldsRef}; use crate::functions::parse_internal; use crate::types::cgp_data::derive_to_fields_match_arms; +/// Derives the `ToFieldsRef` impl for an enum. pub fn derive_to_fields_ref_for_enum(item_enum: &ItemEnum) -> syn::Result { let struct_name = &item_enum.ident; let (impl_generics, type_generics, where_clause) = item_enum.generics.split_for_impl(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs index 447c52ded..d7ff4f96d 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs @@ -5,6 +5,7 @@ use crate::exports::ToFieldsRef; use crate::parse_internal; use crate::types::cgp_data::{FieldLabel, derive_to_fields_constructor}; +/// Derives the `ToFieldsRef` impl for a struct. pub fn derive_to_fields_ref_for_struct(item_struct: &ItemStruct) -> syn::Result { let struct_name = &item_struct.ident; let (impl_generics, type_generics, where_clause) = item_struct.generics.split_for_impl(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs index 725fc1e3c..cf607adaa 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs @@ -6,6 +6,7 @@ use syn::{Error, Fields, Ident, ItemImpl, ItemStruct, LitInt}; use crate::exports::{Cons, Nil, ToFields}; use crate::parse_internal; +/// Derives the `ToFields` impl for a struct. pub fn derive_to_fields_for_struct(item_struct: &ItemStruct) -> syn::Result { let struct_name = &item_struct.ident; let (impl_generics, type_generics, where_clause) = item_struct.generics.split_for_impl(); @@ -36,9 +37,13 @@ pub fn derive_to_fields_for_struct(item_struct: &ItemStruct) -> syn::Result TokenStream, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/item.rs index 1cb7658e1..ead238ed0 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/item.rs @@ -3,12 +3,16 @@ use syn::{Error, Item}; use crate::types::cgp_data::{ItemCgpRecord, ItemCgpVariant}; +/// The parsed `#[derive(CgpData)]` input. pub enum ItemCgpData { + /// A struct. Record(ItemCgpRecord), + /// An enum. Variant(ItemCgpVariant), } impl ItemCgpData { + /// Emits the data's items. pub fn to_items(&self) -> syn::Result> { match self { ItemCgpData::Record(record) => record.to_items(), diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs index c4219bdf3..ce7d63ba8 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs @@ -8,11 +8,14 @@ use crate::types::cgp_data::{ derive_partial_data_impl_from_struct, derive_update_field_impls, }; +/// The parsed `#[derive(CgpRecord)]` input. pub struct ItemCgpRecord { + /// The annotated struct. pub item_struct: ItemStruct, } impl ItemCgpRecord { + /// Emits the record's items. pub fn to_items(&self) -> syn::Result> { let has_field_impls = self.to_has_field_impls()?; let has_fields_impls = self.to_has_fields_impls()?; @@ -27,14 +30,17 @@ impl ItemCgpRecord { Ok(items) } + /// Emits the `HasField` impls. pub fn to_has_field_impls(&self) -> syn::Result> { derive_has_field_impls_from_struct(&self.item_struct) } + /// Emits the `HasFields` impls. pub fn to_has_fields_impls(&self) -> syn::Result> { derive_has_fields_impls_from_struct(&self.item_struct) } + /// Emits the builder and its impls. pub fn to_build_field_items(&self) -> syn::Result> { let item_struct = &self.item_struct; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs index 0de415f06..a67e1845b 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs @@ -8,11 +8,14 @@ use crate::types::cgp_data::{ derive_has_fields_impls_from_enum, derive_partial_data_impl_from_enum, }; +/// The parsed `#[derive(CgpVariant)]` input. pub struct ItemCgpVariant { + /// The annotated enum. pub item_enum: ItemEnum, } impl ItemCgpVariant { + /// Emits the variant's items. pub fn to_items(&self) -> syn::Result> { let has_fields = self.to_has_fields_impls()?; let from_variant_impls = self.to_from_variant_impls()?; @@ -27,14 +30,17 @@ impl ItemCgpVariant { Ok(items) } + /// Emits the `FromVariant` impls. pub fn to_from_variant_impls(&self) -> syn::Result> { derive_from_variant_from_enum(&self.item_enum) } + /// Emits the `HasFields` impls. pub fn to_has_fields_impls(&self) -> syn::Result> { derive_has_fields_impls_from_enum(&self.item_enum) } + /// Emits the extractor and its impls. pub fn to_extract_field_items(&self) -> syn::Result> { let item_enum = &self.item_enum; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_fn/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_fn/item.rs index 8425b03cb..f0d1c17c4 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_fn/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_fn/item.rs @@ -4,12 +4,16 @@ use crate::functions::{extract_and_parse_implicit_args, to_camel_case_str}; use crate::types::attributes::FunctionAttributes; use crate::types::cgp_fn::PreprocessedItemCgpFn; +/// The parsed `#[cgp_fn]` input. pub struct ItemCgpFn { + /// The trait name from the attribute, if given. pub ident: Option, + /// The annotated function. pub item_fn: ItemFn, } impl ItemCgpFn { + /// Extracts the implicits and attributes and resolves the trait name. pub fn preprocess(&self) -> syn::Result { let mut item_fn = self.item_fn.clone(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_fn/preprocessed.rs b/crates/macros/cgp-macro-core/src/types/cgp_fn/preprocessed.rs index 2c98e8004..d4ab56c26 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_fn/preprocessed.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_fn/preprocessed.rs @@ -10,16 +10,24 @@ use crate::traits::AddTypeParamBounds; use crate::types::attributes::FunctionAttributes; use crate::types::implicits::ImplicitArgFields; +/// The checked `#[cgp_fn]` input: the function, its implicits, and its attributes. pub struct PreprocessedItemCgpFn { + /// The trait's name. pub ident: Ident, + /// The annotated function. pub item_fn: ItemFn, + /// The `#[implicit]` arguments. pub implicit_args: ImplicitArgFields, + /// The function's modifier attributes. pub attributes: FunctionAttributes, + /// The function's visibility. pub visibility: Visibility, + /// The function's generics. pub generics: Generics, } impl PreprocessedItemCgpFn { + /// Generates the trait, the blanket impl, and the companion items. pub fn to_items(&self) -> syn::Result> { let item_trait = self.to_item_trait()?; let item_impl = self.to_item_impl()?; @@ -27,6 +35,7 @@ impl PreprocessedItemCgpFn { Ok(vec![item_trait.into(), item_impl.into()]) } + /// Generates the trait the function becomes. pub fn to_item_trait(&self) -> syn::Result { let Self { ident, @@ -92,6 +101,7 @@ impl PreprocessedItemCgpFn { Ok(item_trait) } + /// Generates the blanket impl that calls the function. pub fn to_item_impl(&self) -> syn::Result { let Self { ident, diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/getter_field.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/getter_field.rs index 7498b9d72..92561353f 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/getter_field.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/getter_field.rs @@ -3,19 +3,30 @@ use syn::{Ident, Type}; use crate::types::getter::FieldMode; +/// One getter method parsed into the field it reads. #[derive(Clone)] pub struct GetterField { + /// The field's name. pub field_name: Ident, + /// The field's type. pub field_type: Type, + /// The getter's return type. pub return_type: Type, + /// The `mut` of a `&mut self` receiver. pub receiver_mut: Option, + /// The type of a phantom argument, when the getter takes one. pub phantom_arg_type: Option, + /// How the field is read. pub field_mode: FieldMode, + /// How the getter takes its receiver. pub receiver_mode: ReceiverMode, } +/// How a getter takes its receiver. #[derive(Clone)] pub enum ReceiverMode { + /// The getter takes `self`. SelfReceiver, + /// The getter takes a typed receiver. Type(Box), } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/item.rs index 831eda89c..5142e7627 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/item.rs @@ -5,13 +5,18 @@ use crate::types::cgp_component::EvaluatedCgpComponent; use crate::types::cgp_getter::GetterField; use crate::types::provider_impl::ItemProviderImpls; +/// The evaluated `#[cgp_getter]` component. pub struct ItemCgpGetter { + /// The component's items. pub item_component: EvaluatedCgpComponent, + /// The getter's fields. pub fields: Vec, + /// The getter's associated type, when it declares one. pub field_assoc_type: Option, } impl ItemCgpGetter { + /// Emits the component's items. pub fn to_items(&self) -> syn::Result> { let mut items = self.item_component.to_items()?; @@ -21,6 +26,7 @@ impl ItemCgpGetter { Ok(items) } + /// Emits the `UseFields`, `UseField`, and `WithProvider` impls. pub fn to_item_provider_impls(&self) -> syn::Result { let mut items = ItemProviderImpls::default(); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs index e4b0454e5..b5c484489 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs @@ -10,6 +10,7 @@ use crate::types::provider_impl::ItemProviderImpl; use crate::visitors::get_bounds_and_replace_self_assoc_type; impl ItemCgpGetter { + /// Emits the `UseFields` provider impl. pub fn to_use_fields_impl(&self) -> syn::Result { let provider_trait = &self.item_component.provider_trait; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/use_field.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/use_field.rs index 922398b15..5be00fe38 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/use_field.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/use_field.rs @@ -13,6 +13,7 @@ use crate::types::provider_impl::ItemProviderImpl; use crate::visitors::get_bounds_and_replace_self_assoc_type; impl ItemCgpGetter { + /// Emits the `UseField` provider impl, for a single-field getter. pub fn to_use_field_impl(&self) -> syn::Result> { if self.fields.len() == 1 { let field = &self.fields[0]; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/with_provider.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/with_provider.rs index 1b25fb38a..4e23e3ea1 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/with_provider.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/with_provider.rs @@ -10,6 +10,7 @@ use crate::types::provider_impl::ItemProviderImpl; use crate::visitors::get_bounds_and_replace_self_assoc_type; impl ItemCgpGetter { + /// Emits the `WithProvider` impl, for a single-field getter. pub fn to_with_provider_impl(&self) -> syn::Result> { if self.fields.len() == 1 { let field = &self.fields[0]; @@ -29,6 +30,7 @@ impl ItemCgpGetter { } } + /// Derives the `WithProvider` impl for one field. pub fn derive_with_provider_impl(&self, field: &GetterField) -> syn::Result { let args = &self.item_component.args; let provider_trait = &self.item_component.provider_trait; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_impl/args.rs b/crates/macros/cgp-macro-core/src/types/cgp_impl/args.rs index 14a848a77..f8096f363 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_impl/args.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_impl/args.rs @@ -10,8 +10,11 @@ use crate::types::keywords::New; /// the provider type, and an optional `: ComponentType` override. #[derive(Clone)] pub struct ImplArgs { + /// The `new` keyword, when the provider struct is declared. pub new: Option>, + /// The provider type. pub provider_type: Type, + /// The component override, when given. pub component_type: Option, } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_impl/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_impl/item.rs index 556961c5d..ccc753195 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_impl/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_impl/item.rs @@ -10,7 +10,9 @@ use crate::types::implicits::ImplicitArgFields; /// The raw input stage of `#[cgp_impl]`: the parsed attribute args and the /// `impl` block, before any lowering. pub struct ItemCgpImpl { + /// The impl's arguments. pub args: ImplArgs, + /// The impl block. pub item_impl: ItemImpl, } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_impl/lowered.rs b/crates/macros/cgp-macro-core/src/types/cgp_impl/lowered.rs index 8c7fcd174..03d8b42dd 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_impl/lowered.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_impl/lowered.rs @@ -17,10 +17,15 @@ use crate::visitors::{ /// The header-normalized stage of `#[cgp_impl]`, carrying the resolved context /// type and provider trait path. It owns the consumer-to-provider rewrite. pub struct LoweredCgpImpl { + /// The impl's arguments. pub args: ImplArgs, + /// The impl block. pub item_impl: ItemImpl, + /// The context type. pub context_type: Type, + /// The provider trait's path. pub provider_trait_path: PathWithTypeArgs, + /// The `#[default_impl]` impls. pub default_impls: Vec, } @@ -28,6 +33,7 @@ impl LoweredCgpImpl { /// Rewrites the block into provider-trait form and hands it to /// [`ItemCgpProvider`], or — for the `#[cgp_impl(Self)]` case — returns the /// block unchanged as a bare consumer impl (requiring a `for` clause). + /// Lowers the block into a provider or a bare consumer impl. pub fn lower(&self) -> syn::Result { if self.args.provider_type == parse_internal!(Self) { if self.item_impl.trait_.is_none() { @@ -60,6 +66,7 @@ impl LoweredCgpImpl { /// Performs the consumer-to-provider rewrite: swaps `Self` to the provider, /// inserts the context as the provider trait's leading argument, and runs the /// three `replace_self` visitors to rewrite `self`/`Self` in the body. + /// Rewrites the block into provider-trait form. pub fn to_raw_item_impl(&self) -> syn::Result { let item_impl = &self.item_impl; let context_type = &self.context_type; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_impl/provider_or_bare.rs b/crates/macros/cgp-macro-core/src/types/cgp_impl/provider_or_bare.rs index 92aef56de..ef9cbd864 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_impl/provider_or_bare.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_impl/provider_or_bare.rs @@ -8,7 +8,9 @@ use crate::types::cgp_provider::LoweredCgpProvider; /// (`Provider`) or, for the `#[cgp_impl(Self)]` passthrough, the untouched /// consumer impl (`Bare`). pub enum CgpProviderOrBareImpl { + /// A bare consumer impl. Bare(Box), + /// A lowered provider. Provider(Box), } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_provider/args.rs b/crates/macros/cgp-macro-core/src/types/cgp_provider/args.rs index 9537843a4..de491e422 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_provider/args.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_provider/args.rs @@ -15,7 +15,9 @@ use crate::types::keywords::New; /// carried in from [`#[cgp_impl(new …)]`](../cgp_impl/lowered.rs). #[derive(Clone)] pub struct ProviderArgs { + /// The `new` keyword, when the provider struct is declared. pub new: Option>, + /// The component override, when given. pub component_type: Option, } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_provider/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_provider/item.rs index bc4fe5e90..bb448e246 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_provider/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_provider/item.rs @@ -9,12 +9,16 @@ use crate::types::empty_struct::EmptyStruct; use crate::types::ident::{IdentWithTypeGenerics, PathWithTypeArgs}; use crate::types::provider_impl::ItemProviderImpl; +/// The parsed `#[cgp_provider]` input. pub struct ItemCgpProvider { + /// The provider's arguments. pub args: ProviderArgs, + /// The provider impl. pub item_impl: ItemImpl, } impl ItemCgpProvider { + /// Lowers the provider into its impl, `IsProviderFor` impl, and struct. pub fn lower(&self) -> syn::Result { let provider_struct = self.to_provider_struct()?; @@ -31,6 +35,7 @@ impl ItemCgpProvider { }) } + /// The component the provider implements. pub fn component_type(&self) -> syn::Result { // An explicit `#[cgp_provider(Component)]` / `#[cgp_impl(Provider: Component)]` // override names the component directly; it is a user-written type, so it @@ -69,6 +74,7 @@ impl ItemCgpProvider { parse_internal(component_ident.to_token_stream()) } + /// Builds the provider struct, when the attribute declares one. pub fn to_provider_struct(&self) -> syn::Result> { if self.args.new.is_none() { return Ok(None); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_provider/lower.rs b/crates/macros/cgp-macro-core/src/types/cgp_provider/lower.rs index a74690f93..1f4564231 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_provider/lower.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_provider/lower.rs @@ -4,9 +4,13 @@ use syn::ItemImpl; use crate::types::empty_struct::EmptyStruct; +/// The lowered `#[cgp_provider]` items. pub struct LoweredCgpProvider { + /// The provider impl. pub item_impl: ItemImpl, + /// The `IsProviderFor` impl. pub is_provider_for_impl: ItemImpl, + /// The provider struct, when declared. pub provider_struct: Option, } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_provider/provider_impl_args.rs b/crates/macros/cgp-macro-core/src/types/cgp_provider/provider_impl_args.rs index f8ed7f2b3..622c11fb3 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_provider/provider_impl_args.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_provider/provider_impl_args.rs @@ -8,17 +8,24 @@ use syn::{Error, Lifetime, Type}; use crate::exports::Life; use crate::types::ident::{TypeArg, TypeArgs}; +/// The context and remaining arguments of a provider impl's trait path. pub struct ProviderImplArgs { + /// The context type. pub context_type: Type, + /// The remaining arguments. pub impl_args: Punctuated, } +/// One argument of a provider impl's trait path. pub enum ProviderImplArg { + /// A type argument. Type(Type), + /// A lifetime argument. Life(Lifetime), } impl ProviderImplArgs { + /// Splits the trait path's arguments into the context and the rest. pub fn from_generic_args(generic_args: &TypeArgs) -> syn::Result { let mut impl_args: Punctuated = Punctuated::new(); let mut context_type: Option = None; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs index c5837ac17..331e442e9 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs @@ -7,11 +7,14 @@ use crate::types::cgp_component::EvaluatedCgpComponent; use crate::types::provider_impl::{ItemProviderImpl, ItemProviderImpls}; use crate::visitors::get_bounds_and_replace_self_assoc_type; +/// The evaluated `#[cgp_type]` component. pub struct ItemCgpType { + /// The component's items. pub item_component: EvaluatedCgpComponent, } impl ItemCgpType { + /// Emits the component's items. pub fn to_items(&self) -> syn::Result> { let mut items = self.item_component.to_items()?; @@ -22,10 +25,12 @@ impl ItemCgpType { Ok(items) } + /// Extracts the trait's associated type. pub fn to_trait_item_type(&self) -> syn::Result { extract_item_type_from_trait(&self.item_component.consumer_trait) } + /// Emits the `UseType` and `WithProvider` impls. pub fn to_item_provider_impls(&self) -> syn::Result { let context_name = &self.item_component.args.context_ident; let component_type = self.item_component.args.component_name.to_type(); @@ -106,6 +111,7 @@ impl ItemCgpType { } } +/// Extracts the single associated type from a type trait. pub fn extract_item_type_from_trait(consumer_trait: &ItemTrait) -> syn::Result { if consumer_trait.items.len() != 1 { return Err(Error::new( diff --git a/crates/macros/cgp-macro-core/src/types/check_components/entries.rs b/crates/macros/cgp-macro-core/src/types/check_components/entries.rs index 8955c6350..ea9f8d4b5 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/entries.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/entries.rs @@ -4,12 +4,15 @@ use syn::token::Comma; use crate::types::check_components::{CheckEntry, EvaluatedCheckEntry}; +/// The entries of a `check_components!` table. #[derive(Default)] pub struct CheckEntries { + /// The entries. pub entries: Punctuated, } impl CheckEntries { + /// Expands the entries into their evaluated form. pub fn eval(&self) -> Vec { let mut evaluated_entries = Vec::new(); diff --git a/crates/macros/cgp-macro-core/src/types/check_components/entry.rs b/crates/macros/cgp-macro-core/src/types/check_components/entry.rs index 430f1622a..c4d75b666 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/entry.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/entry.rs @@ -4,12 +4,16 @@ use syn::token::Colon; use crate::types::check_components::{CheckKey, CheckValue, EvaluatedCheckEntry, TypeWithGenerics}; +/// One parsed check entry. pub struct CheckEntry { + /// The components. pub key: CheckKey, + /// The parameters. pub value: Option, } impl CheckEntry { + /// Expands the entry into its evaluated entries. pub fn eval(&self) -> Vec { let mut entries = Vec::new(); diff --git a/crates/macros/cgp-macro-core/src/types/check_components/evaluated_check_entry.rs b/crates/macros/cgp-macro-core/src/types/check_components/evaluated_check_entry.rs index ed621a364..abfb8873f 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/evaluated_check_entry.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/evaluated_check_entry.rs @@ -3,8 +3,12 @@ use syn::Type; use crate::types::check_components::TypeWithGenerics; +/// One check entry after evaluation. pub struct EvaluatedCheckEntry { + /// The component. pub key: Type, + /// The component's parameters. pub value: Option, + /// The span the check is reported on. pub span: Span, } diff --git a/crates/macros/cgp-macro-core/src/types/check_components/key.rs b/crates/macros/cgp-macro-core/src/types/check_components/key.rs index 54973a73f..1ab7b4418 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/key.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/key.rs @@ -3,12 +3,16 @@ use syn::punctuated::Punctuated; use syn::token::{Bracket, Comma}; use syn::{Type, bracketed}; +/// The components a check entry asserts. pub enum CheckKey { + /// One component. Single(Type), + /// Several components. Multi(Punctuated), } impl CheckKey { + /// The components as a list. pub fn to_keys(&self) -> Vec { match self { Self::Single(key) => vec![key.clone()], diff --git a/crates/macros/cgp-macro-core/src/types/check_components/table.rs b/crates/macros/cgp-macro-core/src/types/check_components/table.rs index d5b67504e..d4ae9ebf4 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/table.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/table.rs @@ -12,16 +12,24 @@ use crate::types::check_components::{CheckEntries, EvaluatedCheckEntry, TypeWith use crate::types::generics::ImplGenerics; use crate::types::ident::PathWithTypeArgs; +/// The parsed `check_components!` table. pub struct CheckComponentsTable { + /// The providers to check, when the table uses `#[check_providers]`. pub check_providers: Option>, + /// The table's generic parameters. pub impl_generics: ImplGenerics, + /// The check trait's name. pub trait_name: Ident, + /// The context to check. pub context_type: Type, + /// The table's optional `where` clause. pub where_clause: Option, + /// The components to check. pub check_entries: CheckEntries, } impl CheckComponentsTable { + /// Generates the check trait and its impls. pub fn to_items(&self) -> syn::Result> { let (item_trait, item_impls) = self.eval()?; @@ -31,6 +39,7 @@ impl CheckComponentsTable { Ok(items) } + /// Evaluates the table into the check trait and its impls. pub fn eval(&self) -> syn::Result<(ItemTrait, Vec)> { let mut item_impls = Vec::new(); let unit: Type = parse_internal!(()); diff --git a/crates/macros/cgp-macro-core/src/types/check_components/tables.rs b/crates/macros/cgp-macro-core/src/types/check_components/tables.rs index d28413816..c614667d3 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/tables.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/tables.rs @@ -3,11 +3,14 @@ use syn::parse::{Parse, ParseStream}; use crate::types::check_components::CheckComponentsTable; +/// The parsed `check_components!` tables. pub struct CheckComponentsTables { + /// The tables. pub tables: Vec, } impl CheckComponentsTables { + /// Generates the items for every table. pub fn to_items(&self) -> syn::Result> { let mut items = Vec::new(); diff --git a/crates/macros/cgp-macro-core/src/types/check_components/type_with_generics.rs b/crates/macros/cgp-macro-core/src/types/check_components/type_with_generics.rs index d43bb6d5d..0b5c78054 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/type_with_generics.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/type_with_generics.rs @@ -4,9 +4,12 @@ use syn::token::Lt; use crate::types::generics::ImplGenerics; +/// A type with its own generics. #[derive(Clone)] pub struct TypeWithGenerics { + /// The type. pub ty: Type, + /// The type's generics. pub generics: ImplGenerics, } diff --git a/crates/macros/cgp-macro-core/src/types/check_components/value.rs b/crates/macros/cgp-macro-core/src/types/check_components/value.rs index 67990567a..486541b39 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/value.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/value.rs @@ -5,12 +5,16 @@ use syn::token::{Bracket, Comma}; use crate::types::check_components::TypeWithGenerics; +/// The parameters a check entry asserts. pub enum CheckValue { + /// One parameter. Single(Box), + /// Several parameters. Multi(Punctuated), } impl CheckValue { + /// The parameters as a list. pub fn to_values(&self) -> Vec { match self { Self::Single(value) => vec![value.as_ref().clone()], diff --git a/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/check_params.rs b/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/check_params.rs index cd7b6d52a..61b6a8163 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/check_params.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/check_params.rs @@ -3,14 +3,19 @@ use syn::spanned::Spanned; use syn::token::Comma; use syn::{Attribute, Error, Type}; +/// The `#[check_params]` or `#[skip_check]` attribute on an entry. #[derive(Clone)] pub enum CheckParamsAttribute { + /// No attribute. Default, + /// `#[skip_check]`. Skip, + /// `#[check_params(...)]`. Multi(Punctuated), } impl CheckParamsAttribute { + /// Merges two attributes, rejecting a skip combined with params. pub fn merge(&self, other: &Self) -> syn::Result { let res = match (self, other) { (Self::Default, other) => other.clone(), @@ -30,6 +35,7 @@ impl CheckParamsAttribute { Ok(res) } + /// Parses the entry's check attribute. pub fn parse_attributes(attributes: &[Attribute]) -> syn::Result { if attributes.is_empty() { return Ok(Self::Default); diff --git a/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/item.rs b/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/item.rs index 1716338a7..4bae95a50 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/item.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/item.rs @@ -8,11 +8,14 @@ use crate::types::check_components::{ use crate::types::delegate_and_check_components::ToKeysWithCheckParams; use crate::types::delegate_component::DelegateTable; +/// The parsed `delegate_and_check_components!` input. pub struct ItemDelegateAndCheckComponents { + /// The wiring table. pub table: DelegateTable, } impl ItemDelegateAndCheckComponents { + /// Builds the check table for the wiring. pub fn to_check_components(&self) -> syn::Result { let trait_name = self.check_trait_ident()?; let check_entries = self.to_check_entries()?; @@ -29,6 +32,7 @@ impl ItemDelegateAndCheckComponents { Ok(check_table) } + /// Builds the check entries for the wiring. pub fn to_check_entries(&self) -> syn::Result { let keys = self.table.entries.to_keys_with_check_params()?; @@ -41,6 +45,7 @@ impl ItemDelegateAndCheckComponents { Ok(entries) } + /// The check trait's name. pub fn check_trait_ident(&self) -> syn::Result { let attributes = &self.table.attributes; diff --git a/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/key_with_check_params.rs b/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/key_with_check_params.rs index ebf8ca574..72389fbd6 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/key_with_check_params.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/key_with_check_params.rs @@ -12,12 +12,16 @@ use crate::types::generics::ImplGenerics; /// a key that introduces its own parameters (` FooKey`) binds them on the /// generated check impl rather than referencing them unbound. pub struct KeyWithCheckParams { + /// The key's type. pub key_type: Type, + /// The key's generics. pub generics: ImplGenerics, + /// The check control from the key's attributes. pub check_params: CheckParamsAttribute, } impl KeyWithCheckParams { + /// Builds the check entries for the key. pub fn to_check_entries(&self) -> CheckEntries { match &self.check_params { CheckParamsAttribute::Default => { diff --git a/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/to_keys_with_check_params.rs b/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/to_keys_with_check_params.rs index 368effa49..13420ce3b 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/to_keys_with_check_params.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_and_check_components/to_keys_with_check_params.rs @@ -4,7 +4,9 @@ use crate::types::delegate_component::{ ValidateAttributes, }; +/// Converts a construct into keys paired with their check control. pub trait ToKeysWithCheckParams { + /// The keys and their check control. fn to_keys_with_check_params(&self) -> syn::Result>; } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/entries.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/entries.rs index 757ada929..82af52544 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/entries.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/entries.rs @@ -14,7 +14,9 @@ use crate::types::delegate_component::{ /// is what a `cgp_namespace!` header written without a body parses to. #[derive(Debug, Clone, Default)] pub struct DelegateEntries { + /// The leading statements. pub statements: Vec, + /// The mappings. pub entries: Punctuated, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/key/combined.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/key/combined.rs index 9df468f0b..053c3636d 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/key/combined.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/key/combined.rs @@ -11,8 +11,11 @@ use crate::types::generics::ImplGenerics; /// key, a leading `[` a `Multi` (array) key, otherwise a `Single` key. #[derive(Debug, Clone)] pub enum DelegateKey { + /// A single key. Single(SingleDelegateKey), + /// An array key. Multi(MultiDelegateKey), + /// An `@`-path key. Path(PathDelegateKey), } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/key/eval.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/key/eval.rs index 455e4bf1d..69cd4bb3e 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/key/eval.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/key/eval.rs @@ -4,7 +4,9 @@ use syn::{Generics, Type}; /// A lowered key: the key type plus the generics it introduces. One source key /// can yield several of these (array keys, brace groups in a path). pub struct EvaluatedDelegateKey { + /// The key's generics. pub generics: Generics, + /// The key's type. pub key: Type, /// The span of the source token the key was written as, carried separately /// because `key` may be a synthesized type (a `PathCons<..>` nest for an @@ -15,5 +17,6 @@ pub struct EvaluatedDelegateKey { /// Lower a key form into its evaluated keys. pub trait EvalDelegateKey { + /// Lowers the key. fn eval(&self) -> syn::Result>; } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/key/multi.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/key/multi.rs index fe909d3ea..205da1be2 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/key/multi.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/key/multi.rs @@ -10,7 +10,9 @@ use crate::types::delegate_component::{EvalDelegateKey, EvaluatedDelegateKey, Si /// several components share a single value. #[derive(Debug, Clone)] pub struct MultiDelegateKey { + /// The key's attributes. pub attributes: Vec, + /// The bracketed keys. pub keys: Punctuated, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/key/path.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/key/path.rs index 2893f0381..0f9a9b127 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/key/path.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/key/path.rs @@ -14,9 +14,13 @@ use crate::types::path::{PathElement, PathHead}; /// time; a brace group in the path expands to one key per element. #[derive(Debug, Clone)] pub struct PathDelegateKey { + /// The key's attributes. pub attributes: Vec, + /// The key's generics. pub generics: ImplGenerics, + /// The `@` token. pub at: At, + /// The path head. pub path: PathHead, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/key/single.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/key/single.rs index 742e2a09c..30972fc1c 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/key/single.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/key/single.rs @@ -9,8 +9,11 @@ use crate::types::generics::ImplGenerics; /// keyed impl carrying those generics. #[derive(Debug, Clone)] pub struct SingleDelegateKey { + /// The key's attributes. pub attributes: Vec, + /// The key's generics. pub generics: ImplGenerics, + /// The key's type. pub ty: Type, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/combined.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/combined.rs index 9f0db22af..07224a0a4 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/combined.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/combined.rs @@ -10,8 +10,11 @@ use crate::types::delegate_component::{ /// `->` is Direct, `=>` is Redirect. #[derive(Debug, Clone)] pub enum DelegateMapping { + /// A `Key: Value` mapping. Normal(NormalDelegateMapping), + /// A `Key -> Value` mapping. Direct(DirectDelegateMapping), + /// A `Key => @path` mapping. Redirect(RedirectDelegateMapping), } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/direct.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/direct.rs index fe254d5f0..0581c5263 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/direct.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/direct.rs @@ -15,8 +15,11 @@ use crate::types::delegate_component::{ /// matching `Value: DelegateComponent` bound. #[derive(Debug, Clone)] pub struct DirectDelegateMapping { + /// The key. pub key: DelegateKey, + /// The `->` arrow. pub arrow: RArrow, + /// The table to forward to. pub value: DelegateValue, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/eval.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/eval.rs index 17315f22b..5ec49d771 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/eval.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/eval.rs @@ -9,9 +9,13 @@ use crate::functions::{ /// The flat form every key, value, and statement collapses to; it renders the /// impl pair for one wiring entry. pub struct EvaluatedDelegateEntry { + /// The table type. pub table_type: Type, + /// The entry's generics. pub generics: Generics, + /// The component key. pub key: Type, + /// The provider value. pub value: Type, /// The span the entry's impls are re-spanned onto, so a coherence conflict is /// reported on the entry the user wrote. Sourced from the key's original token @@ -32,17 +36,20 @@ pub struct EvaluatedDelegateEntry { /// Lower a construct into a single evaluated entry. pub trait EvalDelegateEntry { + /// Lowers the construct. fn eval_entry(&self, table_type: &Type) -> syn::Result; } /// Lower a construct into a flat list of evaluated entries (a key or statement /// may expand to several). pub trait EvalDelegateEntries { + /// Lowers the construct. fn eval_entries(&self, table_type: &Type) -> syn::Result>; } impl EvaluatedDelegateEntry { /// Emit `impl DelegateComponent for TableType { type Delegate = Value; }`. + /// Emits the `DelegateComponent` impl for the entry. pub fn build_delegate_component_impl( &self, outer_generics: &Generics, @@ -80,6 +87,7 @@ impl EvaluatedDelegateEntry { /// transitive dependency stays diagnosable. `__Params__` is `?Sized`, as on /// the trait, so a component used at an unsized parameter (`str`, making the /// params tuple `(Life<'a>, str)` unsized) still resolves through the table. + /// Emits the forwarding `IsProviderFor` impl for the entry. pub fn build_is_provider_for_impl(&self, outer_generics: &Generics) -> syn::Result { let table_type = &self.table_type; @@ -149,6 +157,7 @@ impl EvaluatedDelegateEntry { /// Emit `impl namespace_trait for Key { type Delegate = Value; }`, used by /// the namespace preset machinery instead of a direct `DelegateComponent` impl. + /// Emits the namespace trait impl for the entry. pub fn build_namespace_impl( &self, namespace_trait: &Type, diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/mode.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/mode.rs index 1c925d405..102b5d827 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/mode.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/mode.rs @@ -4,8 +4,11 @@ use syn::token::{Colon, FatArrow, RArrow}; /// The operator between a key and its value, peeked to select the mapping /// variant: `:` Normal, `->` Direct, `=>` Redirect. pub enum DelegateMode { + /// `:`. Normal(Colon), + /// `->`. Direct(RArrow), + /// `=>`. Redirect(FatArrow), } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/normal.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/normal.rs index e3f96a1d7..fac886643 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/normal.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/normal.rs @@ -11,8 +11,11 @@ use crate::types::delegate_component::{ /// value type directly. #[derive(Debug, Clone)] pub struct NormalDelegateMapping { + /// The key. pub key: DelegateKey, + /// The colon. pub colon: Colon, + /// The provider value. pub value: DelegateValue, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/redirect.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/redirect.rs index ba0ac6dea..abf47142d 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/redirect.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/mapping/redirect.rs @@ -12,8 +12,11 @@ use crate::types::path::UniPath; /// `Delegate` becomes `RedirectLookup`. #[derive(Debug, Clone)] pub struct RedirectDelegateMapping { + /// The key. pub key: DelegateKey, + /// The `=>` arrow. pub arrow: FatArrow, + /// The path to redirect along. pub value: UniPath, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/combined.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/combined.rs index 038f15310..efb1554de 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/combined.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/combined.rs @@ -13,14 +13,18 @@ use crate::types::keywords::{Namespace, Open}; /// lower into the same flat entry list as ordinary mappings. #[derive(Debug, Clone)] pub enum DelegateStatement { + /// A `namespace` statement. Namespace(NamespaceDelegateStatement), + /// An `open` statement. Open(OpenDelegateStatement), + /// A `for` statement. For(Box), } impl DelegateStatement { /// Peek whether the input begins with a statement keyword, so all leading /// statements are consumed before the mappings. + /// Returns whether the input begins with a statement keyword. pub fn peek_statement(input: ParseStream) -> bool { input.peek_keyword::() || input.peek_keyword::() || input.peek(For) } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/eval.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/eval.rs index 10506aa15..c0afcc404 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/eval.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/eval.rs @@ -7,11 +7,13 @@ use crate::types::ident::PathWithTypeArgs; /// Lower a `namespace`/`for` statement into intermediate for-entries. pub trait EvalForEntries { + /// Lowers the statement's entries. fn eval_for_entries(&self, table_type: &Type) -> syn::Result>; } /// Lower a construct into a single for-entry. pub trait EvalForEntry { + /// Lowers the construct. fn eval_for_entry(&self, table_type: &Type) -> syn::Result; } @@ -19,12 +21,19 @@ pub trait EvalForEntry { /// `__Key__: Namespace<.., Delegate = __Value__>` bound and the final /// `EvaluatedDelegateEntry` are built. pub struct EvaluatedForEntry { + /// The entry's generics. pub generics: Generics, + /// The table type. pub table_type: Type, + /// The loop's key parameter. pub for_key: Ident, + /// The loop's value parameter. pub for_value: Ident, + /// The namespace the entry reads from. pub namespace: PathWithTypeArgs, + /// The mapping's key. pub mapping_key: Type, + /// The mapping's value. pub mapping_value: Type, /// The diagnostic span carried through to the entry's impls; sourced from the /// user token behind the statement (the `namespace` name, or a `for` mapping's diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/for_loop.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/for_loop.rs index 88b956117..8dd0c6cad 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/for_loop.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/for_loop.rs @@ -15,15 +15,25 @@ use crate::types::ident::PathWithTypeArgs; /// with the table type and a `Delegate =` binding appended. #[derive(Debug, Clone)] pub struct ForDelegateStatement { + /// The `for` keyword. pub for_token: For, + /// The `<` of the loop's parameters. pub lt: Lt, + /// The key parameter. pub key: Ident, + /// The comma between the parameters. pub comma: Comma, + /// The value parameter. pub value: Ident, + /// The `>` of the loop's parameters. pub gt: Gt, + /// The `in` keyword. pub in_token: In, + /// The table the loop reads from. pub namespace: PathWithTypeArgs, + /// The loop's optional `where` clause. pub where_clause: Option, + /// The mappings the loop emits. pub mappings: Punctuated, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/namespace.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/namespace.rs index 3d02f09bc..5b2a073aa 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/namespace.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/namespace.rs @@ -15,8 +15,11 @@ use crate::types::keywords::Namespace; /// on `__Key__: SomeNamespace`. #[derive(Debug, Clone)] pub struct NamespaceDelegateStatement { + /// The `namespace` keyword. pub namespace: Keyword, + /// The namespace's name. pub ident: Ident, + /// The statement's semicolon. pub semi: Semi, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/open.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/open.rs index f9f156f6f..f1a3cb3dd 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/statement/open.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/statement/open.rs @@ -16,8 +16,11 @@ use crate::types::keywords::Open; /// the `@Component.Key` mappings that follow dispatch on the redirect path. #[derive(Debug, Clone)] pub struct OpenDelegateStatement { + /// The `open` keyword. pub open: Keyword, + /// The components to open. pub components: Punctuated, + /// The statement's semicolon. pub semi: Semi, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/table/inner.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/table/inner.rs index c649b6ab3..fdf85fa94 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/table/inner.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/table/inner.rs @@ -9,6 +9,7 @@ use crate::types::generics::TypeGenerics; /// Collect every nested `UseDelegate` table reachable from a /// construct, so `DelegateTable::eval` can emit each inner table's own items. pub trait ExtractInnerDelegateTables { + /// The nested tables. fn extract_inner_tables(&self) -> Vec; } @@ -16,8 +17,11 @@ pub trait ExtractInnerDelegateTables { /// evaluated exactly like a top-level table, keyed on its own identifier. #[derive(Debug, Clone)] pub struct InnerDelegateTable { + /// The table's name. pub table_ident: Ident, + /// The table's generic parameters. pub table_generics: TypeGenerics, + /// The table's entries. pub entries: DelegateEntries, } @@ -43,6 +47,7 @@ impl Parse for InnerDelegateTable { } impl InnerDelegateTable { + /// Builds the table's type. pub fn build_table_type(&self) -> syn::Result { let ident = &self.table_ident; let type_generics = self.table_generics.split_for_impl().1; @@ -51,6 +56,7 @@ impl InnerDelegateTable { Ok(ty) } + /// Builds the table's marker struct. pub fn build_table_struct(&self) -> EmptyStruct { let ident = self.table_ident.clone(); let generics = self.table_generics.generics.clone(); @@ -63,6 +69,7 @@ impl InnerDelegateTable { } } + /// Builds the table's impls. pub fn build_impls(&self) -> syn::Result> { let table_type = self.build_table_type()?; self.entries.build_impls(&table_type, &self.table_generics) diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/table/main.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/table/main.rs index 0f7bb8f96..1d0a4328d 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/table/main.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/table/main.rs @@ -15,17 +15,24 @@ use crate::types::keywords::New; /// The whole parsed `delegate_components!` body: an optional generic list and /// `new` keyword, the target type, and its braced table of entries. pub struct DelegateTable { + /// The table's outer attributes. pub attributes: Vec, + /// The table's generic parameters. pub impl_generics: ImplGenerics, + /// The `new` keyword, when the table declares its struct. pub new: Option>, + /// The target type. pub table_type: Type, + /// The table's entries. pub entries: DelegateEntries, } /// The lowered table: the generated impls and any structs (`new` target and /// lifted inner tables). Its `ToTokens` emits the structs first, then the impls. pub struct EvaluatedDelegateTable { + /// The generated impls. pub item_impls: Vec, + /// The generated structs. pub item_structs: Vec, } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/validate_attributes.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/validate_attributes.rs index 13070dc7e..3d589c158 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/validate_attributes.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/validate_attributes.rs @@ -10,7 +10,9 @@ use crate::types::delegate_component::{ At the moment, no attribute is supported, so all attributes are rejected. */ +/// Rejects attributes a construct does not support. pub trait ValidateAttributes { + /// Rejects the unsupported attributes. fn validate_attributes(&self) -> syn::Result<()>; } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/value/combined.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/value/combined.rs index 66d409394..4a1577e90 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/value/combined.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/value/combined.rs @@ -10,7 +10,9 @@ use crate::types::delegate_component::{ /// a legacy `Wrapper` value that opens a nested table. #[derive(Debug, Clone)] pub enum DelegateValue { + /// A plain provider type. Type(Type), + /// A legacy nested table. WithTable(DelegateValueWithInnerTable), } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/value/eval.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/value/eval.rs index 5bd73aaee..fb2ad9fe6 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/value/eval.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/value/eval.rs @@ -2,5 +2,6 @@ use syn::Type; /// Lower a mapping value into the provider `Type` stored as the entry's `Delegate`. pub trait EvalDelegateValue { + /// Lowers the value. fn eval(&self) -> syn::Result; } diff --git a/crates/macros/cgp-macro-core/src/types/delegate_component/value/inner_table.rs b/crates/macros/cgp-macro-core/src/types/delegate_component/value/inner_table.rs index 2f417be06..29562ea95 100644 --- a/crates/macros/cgp-macro-core/src/types/delegate_component/value/inner_table.rs +++ b/crates/macros/cgp-macro-core/src/types/delegate_component/value/inner_table.rs @@ -14,8 +14,11 @@ use crate::types::keywords::New; /// out to become its own struct and impls. #[derive(Debug, Clone)] pub struct DelegateValueWithInnerTable { + /// The `new` keyword. pub new: Keyword, + /// The wrapper provider's name. pub wrapper_ident: Ident, + /// The nested table. pub inner_table: InnerDelegateTable, } diff --git a/crates/macros/cgp-macro-core/src/types/empty_struct.rs b/crates/macros/cgp-macro-core/src/types/empty_struct.rs index 5bb5a7868..97826f8b7 100644 --- a/crates/macros/cgp-macro-core/src/types/empty_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/empty_struct.rs @@ -5,8 +5,11 @@ use syn::{GenericParam, Generics, Ident, ItemStruct, Type, parse_quote}; use crate::exports::Life; +/// A generated empty struct, with its optional doc line. pub struct EmptyStruct { + /// The struct's name. pub ident: Ident, + /// The struct's generics. pub generics: Generics, /// The doc line emitted above the struct, so a crate that enables /// `missing_docs` does not report the generated item. @@ -14,6 +17,7 @@ pub struct EmptyStruct { } impl EmptyStruct { + /// Renders the struct as an `ItemStruct`. pub fn to_item_struct(&self) -> ItemStruct { parse_quote!(#self) } diff --git a/crates/macros/cgp-macro-core/src/types/field/field_name.rs b/crates/macros/cgp-macro-core/src/types/field/field_name.rs index 253bc360f..6198697b2 100644 --- a/crates/macros/cgp-macro-core/src/types/field/field_name.rs +++ b/crates/macros/cgp-macro-core/src/types/field/field_name.rs @@ -4,8 +4,11 @@ use syn::Ident; use crate::types::field::{Index, Symbol}; +/// A field's type-level name. pub enum FieldName { + /// A named field. Ident(Symbol), + /// A tuple field. Index(Index), } diff --git a/crates/macros/cgp-macro-core/src/types/field/has_field_bound.rs b/crates/macros/cgp-macro-core/src/types/field/has_field_bound.rs index e41244b3d..d1fccf691 100644 --- a/crates/macros/cgp-macro-core/src/types/field/has_field_bound.rs +++ b/crates/macros/cgp-macro-core/src/types/field/has_field_bound.rs @@ -6,10 +6,15 @@ use syn::token::Mut; use crate::exports::{HasField, HasFieldMut, OptionAsRef}; use crate::types::getter::FieldMode; +/// The `HasField` or `HasFieldMut` bound a field read requires. pub struct HasFieldBound { + /// The field's type. pub field_type: Type, + /// The `mut` of a mutable read. pub field_mut: Option, + /// How the field is read. pub field_mode: FieldMode, + /// The field's tag type. pub tag_type: Type, } diff --git a/crates/macros/cgp-macro-core/src/types/field/index.rs b/crates/macros/cgp-macro-core/src/types/field/index.rs index d5b4b187d..b47c3105e 100644 --- a/crates/macros/cgp-macro-core/src/types/field/index.rs +++ b/crates/macros/cgp-macro-core/src/types/field/index.rs @@ -4,8 +4,11 @@ use syn::LitInt; use crate::exports::Index as Delta; +/// A tuple field's position as a type-level index. pub struct Index { + /// The position. pub index: usize, + /// The source span. pub span: Span, } diff --git a/crates/macros/cgp-macro-core/src/types/field/symbol.rs b/crates/macros/cgp-macro-core/src/types/field/symbol.rs index 305e5d61e..d45e6a647 100644 --- a/crates/macros/cgp-macro-core/src/types/field/symbol.rs +++ b/crates/macros/cgp-macro-core/src/types/field/symbol.rs @@ -6,13 +6,17 @@ use syn::{Ident, LitStr, Type, parse_quote}; use crate::traits::ToType; +/// A type-level string parsed from an identifier or a string literal. #[derive(Debug, Clone)] pub struct Symbol { + /// The string's value. pub ident: String, + /// The source span. pub span: Span, } impl Symbol { + /// Builds a symbol from an identifier. pub fn from_ident(ident: Ident) -> Self { Self { // `unraw` strips a raw identifier's `r#` prefix so a field written diff --git a/crates/macros/cgp-macro-core/src/types/generics/impl_generics.rs b/crates/macros/cgp-macro-core/src/types/generics/impl_generics.rs index f29f27c6c..6da3a9f23 100644 --- a/crates/macros/cgp-macro-core/src/types/generics/impl_generics.rs +++ b/crates/macros/cgp-macro-core/src/types/generics/impl_generics.rs @@ -7,8 +7,10 @@ use syn::{Error, Generics}; use crate::functions::parse_internal; +/// The generic parameters of an impl block. #[derive(Debug, Clone, Default)] pub struct ImplGenerics { + /// The parameters. pub generics: Generics, } diff --git a/crates/macros/cgp-macro-core/src/types/generics/type_generics.rs b/crates/macros/cgp-macro-core/src/types/generics/type_generics.rs index d62d11d59..3239dcec1 100644 --- a/crates/macros/cgp-macro-core/src/types/generics/type_generics.rs +++ b/crates/macros/cgp-macro-core/src/types/generics/type_generics.rs @@ -21,6 +21,7 @@ use crate::functions::parse_internal; /// [`TypeGenericParams`]: crate::types::ident::TypeGenericParams #[derive(Debug, Clone, Default)] pub struct TypeGenerics { + /// The parameters. pub generics: Generics, } diff --git a/crates/macros/cgp-macro-core/src/types/getter/context_arg.rs b/crates/macros/cgp-macro-core/src/types/getter/context_arg.rs index d9f87a5e3..ab00b5ef0 100644 --- a/crates/macros/cgp-macro-core/src/types/getter/context_arg.rs +++ b/crates/macros/cgp-macro-core/src/types/getter/context_arg.rs @@ -1,7 +1,10 @@ use syn::Type; +/// How a getter takes its context. #[derive(Clone)] pub enum ContextArg { + /// The getter takes `self`. SelfArg, + /// The getter takes a typed context. Type(Box), } diff --git a/crates/macros/cgp-macro-core/src/types/getter/field_mode.rs b/crates/macros/cgp-macro-core/src/types/getter/field_mode.rs index bbc65fc83..2fd8b1298 100644 --- a/crates/macros/cgp-macro-core/src/types/getter/field_mode.rs +++ b/crates/macros/cgp-macro-core/src/types/getter/field_mode.rs @@ -8,12 +8,19 @@ use crate::exports::{MRef, OptionAsRef}; /// getter method's return type by [`parse_field_type`](crate::functions::parse_field_type). #[derive(Clone, Eq, PartialEq)] pub enum FieldMode { + /// Return the field by reference. Reference, + /// Return an `Option` field by reference. OptionRef, + /// Return an `Option` field as an `Option<&str>`. OptionStr, + /// Return the field as an [`MRef`]. MRef, + /// Return the field as a `&str`. Str, + /// Return a copy of the field. Copy, + /// Return the field as a slice. Slice, } diff --git a/crates/macros/cgp-macro-core/src/types/getter/get_field_expr.rs b/crates/macros/cgp-macro-core/src/types/getter/get_field_expr.rs index 5f23a68d1..2affec535 100644 --- a/crates/macros/cgp-macro-core/src/types/getter/get_field_expr.rs +++ b/crates/macros/cgp-macro-core/src/types/getter/get_field_expr.rs @@ -6,9 +6,13 @@ use syn::token::Mut; use crate::exports::{HasField, HasFieldMut}; use crate::types::field::FieldName; +/// A fully qualified field read. pub struct GetFieldExpr { + /// The receiver. pub receiver: Expr, + /// The `mut` of a mutable read. pub field_mut: Option, + /// The field's name. pub field_name: FieldName, } diff --git a/crates/macros/cgp-macro-core/src/types/getter/get_field_with_mode_expr.rs b/crates/macros/cgp-macro-core/src/types/getter/get_field_with_mode_expr.rs index e5a57b831..a918df8e3 100644 --- a/crates/macros/cgp-macro-core/src/types/getter/get_field_with_mode_expr.rs +++ b/crates/macros/cgp-macro-core/src/types/getter/get_field_with_mode_expr.rs @@ -3,8 +3,11 @@ use quote::ToTokens; use crate::types::getter::{FieldMode, GetFieldExpr}; +/// A field read with its conversion applied. pub struct GetFieldWithModeExpr { + /// The field read. pub get_field: GetFieldExpr, + /// The conversion to apply. pub field_mode: FieldMode, } diff --git a/crates/macros/cgp-macro-core/src/types/getter/method.rs b/crates/macros/cgp-macro-core/src/types/getter/method.rs index 70ac17edd..86cb556b1 100644 --- a/crates/macros/cgp-macro-core/src/types/getter/method.rs +++ b/crates/macros/cgp-macro-core/src/types/getter/method.rs @@ -7,6 +7,7 @@ use crate::functions::parse_internal; use crate::types::cgp_getter::GetterField; use crate::types::getter::ContextArg; +/// Builds a getter method's body from its field. pub fn derive_getter_method( context_arg: &ContextArg, getter_field: &GetterField, @@ -22,14 +23,20 @@ pub fn derive_getter_method( .to_item_fn() } +/// A getter method to generate. pub struct GetterMethod { + /// How the getter takes its context. pub context_arg: ContextArg, + /// The field the getter reads. pub getter_field: GetterField, + /// The field's tag type. pub tag_type: Type, + /// The provider to call, when the getter is wired. pub provider_ident: Option, } impl GetterMethod { + /// Builds the getter method. pub fn to_item_fn(&self) -> syn::Result { let Self { context_arg, diff --git a/crates/macros/cgp-macro-core/src/types/ident/ident_with_type_args.rs b/crates/macros/cgp-macro-core/src/types/ident/ident_with_type_args.rs index 3110c8fc9..2fa5b7c68 100644 --- a/crates/macros/cgp-macro-core/src/types/ident/ident_with_type_args.rs +++ b/crates/macros/cgp-macro-core/src/types/ident/ident_with_type_args.rs @@ -15,7 +15,9 @@ use crate::types::ident::TypeArgs; /// [`PathWithTypeArgs`]: crate::types::ident::PathWithTypeArgs #[derive(Debug, Clone)] pub struct IdentWithTypeArgs { + /// The identifier. pub ident: Ident, + /// The type arguments. pub type_args: TypeArgs, } diff --git a/crates/macros/cgp-macro-core/src/types/ident/ident_with_type_generics.rs b/crates/macros/cgp-macro-core/src/types/ident/ident_with_type_generics.rs index ecccf5263..b6e8cb249 100644 --- a/crates/macros/cgp-macro-core/src/types/ident/ident_with_type_generics.rs +++ b/crates/macros/cgp-macro-core/src/types/ident/ident_with_type_generics.rs @@ -9,11 +9,14 @@ use crate::types::ident::TypeGenericParams; /// list, e.g. `Foo`, `Foo`, or `Bar<'a, C>`. #[derive(Debug, Clone)] pub struct IdentWithTypeGenerics { + /// The identifier. pub ident: Ident, + /// The definition-site generic parameters. pub type_generics: TypeGenericParams, } impl IdentWithTypeGenerics { + /// Renders the identifier and its generics as a type. pub fn to_type(&self) -> Type { parse_quote!(#self) } diff --git a/crates/macros/cgp-macro-core/src/types/ident/type_arg.rs b/crates/macros/cgp-macro-core/src/types/ident/type_arg.rs index aa0a161a9..573c828b5 100644 --- a/crates/macros/cgp-macro-core/src/types/ident/type_arg.rs +++ b/crates/macros/cgp-macro-core/src/types/ident/type_arg.rs @@ -99,10 +99,12 @@ impl ToTokens for TypeArg { /// an empty list always renders as nothing. #[derive(Debug, Clone, Default)] pub struct TypeArgs { + /// The arguments. pub args: Punctuated, } impl TypeArgs { + /// Returns whether the list is empty. pub fn is_empty(&self) -> bool { self.args.is_empty() } diff --git a/crates/macros/cgp-macro-core/src/types/ident/type_generic_param.rs b/crates/macros/cgp-macro-core/src/types/ident/type_generic_param.rs index 8616bc775..ef491337a 100644 --- a/crates/macros/cgp-macro-core/src/types/ident/type_generic_param.rs +++ b/crates/macros/cgp-macro-core/src/types/ident/type_generic_param.rs @@ -40,9 +40,13 @@ pub enum TypeGenericParam { /// `Bar`. Defaults (`= 0`) are deliberately not represented. #[derive(Debug, Clone)] pub struct ConstGenericParam { + /// The `const` keyword. pub const_token: Const, + /// The parameter's name. pub ident: Ident, + /// The colon before the type. pub colon: Colon, + /// The parameter's type. pub ty: Type, } @@ -146,10 +150,12 @@ impl ToTokens for TypeGenericParam { /// so a parsed `<>` round-trips back to no angle brackets. #[derive(Debug, Clone, Default)] pub struct TypeGenericParams { + /// The parameters. pub params: Punctuated, } impl TypeGenericParams { + /// Returns whether the list is empty. pub fn is_empty(&self) -> bool { self.params.is_empty() } diff --git a/crates/macros/cgp-macro-core/src/types/implicits/arg_field.rs b/crates/macros/cgp-macro-core/src/types/implicits/arg_field.rs index ff66912a6..2dc7de8de 100644 --- a/crates/macros/cgp-macro-core/src/types/implicits/arg_field.rs +++ b/crates/macros/cgp-macro-core/src/types/implicits/arg_field.rs @@ -5,16 +5,23 @@ use crate::parse_internal; use crate::types::field::{FieldName, HasFieldBound}; use crate::types::getter::{FieldMode, GetFieldExpr, GetFieldWithModeExpr}; +/// One `#[implicit]` argument parsed into the field it reads. #[derive(Clone, Eq, PartialEq)] pub struct ImplicitArgField { + /// The field's name. pub field_name: Ident, + /// The field's type. pub field_type: Type, + /// The `mut` of a `&mut` argument. pub field_mut: Option, + /// How the field is read. pub field_mode: FieldMode, + /// The argument's type. pub arg_type: Type, } impl ImplicitArgField { + /// Builds the `HasField` bound the argument requires. pub fn to_has_field_bound(&self) -> syn::Result { let field_name = FieldName::from(self.field_name.clone()); let tag_type = parse_internal!(#field_name); @@ -27,6 +34,7 @@ impl ImplicitArgField { }) } + /// Builds the statement that reads the field into the argument. pub fn to_statement(&self) -> syn::Result { let field_name = &self.field_name; let arg_type = &self.arg_type; diff --git a/crates/macros/cgp-macro-core/src/types/implicits/arg_fields.rs b/crates/macros/cgp-macro-core/src/types/implicits/arg_fields.rs index 600e212f0..45cac923f 100644 --- a/crates/macros/cgp-macro-core/src/types/implicits/arg_fields.rs +++ b/crates/macros/cgp-macro-core/src/types/implicits/arg_fields.rs @@ -7,12 +7,15 @@ use crate::parse_internal; use crate::traits::ToTypeParamBounds; use crate::types::implicits::ImplicitArgField; +/// The `#[implicit]` arguments of a function or impl block. #[derive(Default)] pub struct ImplicitArgFields { + /// The arguments. pub fields: Vec, } impl ImplicitArgFields { + /// Creates the list from its fields. pub fn new(fields: Vec) -> Self { Self { fields } } @@ -32,6 +35,7 @@ impl ToTypeParamBounds for ImplicitArgFields { } impl ImplicitArgFields { + /// Prepends the field reads to a block. pub fn prepend_to_block(&self, block: &mut Block) -> syn::Result<()> { let block_statements = core::mem::take(&mut block.stmts); @@ -45,6 +49,7 @@ impl ImplicitArgFields { Ok(()) } + /// Extracts the implicit arguments from an impl block's methods. pub fn extract_from_impl_items(impl_items: &mut [ImplItem]) -> syn::Result { let mut all_fields = Vec::new(); diff --git a/crates/macros/cgp-macro-core/src/types/keyword.rs b/crates/macros/cgp-macro-core/src/types/keyword.rs index 812e34674..642a5b593 100644 --- a/crates/macros/cgp-macro-core/src/types/keyword.rs +++ b/crates/macros/cgp-macro-core/src/types/keyword.rs @@ -7,8 +7,11 @@ use syn::{Error, Ident}; use crate::traits::IsKeyword; +/// A parsed keyword, carrying its span. pub struct Keyword { + /// The keyword's span. pub span: Span, + /// The keyword marker. pub phantom: PhantomData, } diff --git a/crates/macros/cgp-macro-core/src/types/mod.rs b/crates/macros/cgp-macro-core/src/types/mod.rs index abd1530bf..fb1a52f6d 100644 --- a/crates/macros/cgp-macro-core/src/types/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/mod.rs @@ -1,27 +1,54 @@ +/// The parsed modifier attributes. pub mod attributes; +/// The AST for `#[blanket_trait]`. pub mod blanket_trait; +/// The AST for `#[cgp_auto_getter]`. pub mod cgp_auto_getter; +/// The AST for `#[cgp_component]`. pub mod cgp_component; +/// The AST for the extensible-data derives. pub mod cgp_data; +/// The AST for `#[cgp_fn]`. pub mod cgp_fn; +/// The AST for `#[cgp_getter]`. pub mod cgp_getter; +/// The AST for `#[cgp_impl]`. pub mod cgp_impl; +/// The AST for `#[cgp_provider]` and `#[cgp_new_provider]`. pub mod cgp_provider; +/// The AST for `#[cgp_type]`. pub mod cgp_type; +/// The AST for `check_components!`. pub mod check_components; +/// The AST for `delegate_and_check_components!`. pub mod delegate_and_check_components; +/// The AST for `delegate_components!`. pub mod delegate_component; +/// The AST for a generated empty struct. pub mod empty_struct; +/// The AST for field access and bounds. pub mod field; +/// The AST for generic parameters. pub mod generics; +/// The AST for getter methods. pub mod getter; +/// The AST for identifiers and their generics. pub mod ident; +/// The AST for `#[implicit]` arguments. pub mod implicits; +/// The AST for keyword markers. pub mod keyword; +/// The keyword markers the parsers use. pub mod keywords; +/// The AST for `cgp_namespace!`. pub mod namespace; +/// The AST for type-level paths. pub mod path; +/// The AST for `Product!`. pub mod product; +/// The AST for a provider impl. pub mod provider_impl; +/// The AST for struct and enum shapes. pub mod shape; +/// The AST for `Sum!`. pub mod sum; diff --git a/crates/macros/cgp-macro-core/src/types/namespace/eval.rs b/crates/macros/cgp-macro-core/src/types/namespace/eval.rs index 7b3afc14c..d41920167 100644 --- a/crates/macros/cgp-macro-core/src/types/namespace/eval.rs +++ b/crates/macros/cgp-macro-core/src/types/namespace/eval.rs @@ -4,9 +4,13 @@ use syn::{ItemImpl, ItemStruct, ItemTrait}; use crate::types::empty_struct::EmptyStruct; +/// The evaluated `cgp_namespace!` table. pub struct EvaluatedNamespaceTable { + /// The generated impls. pub item_impls: Vec, + /// The namespace trait, when declared. pub item_trait: Option, + /// The namespace struct, when declared. pub item_struct: Option, /// The structs declared for nested `Wrapper` values lifted out /// of the body, mirroring `EvaluatedDelegateTable::item_structs`. Their diff --git a/crates/macros/cgp-macro-core/src/types/namespace/inherit.rs b/crates/macros/cgp-macro-core/src/types/namespace/inherit.rs index fd607c2d4..501233aec 100644 --- a/crates/macros/cgp-macro-core/src/types/namespace/inherit.rs +++ b/crates/macros/cgp-macro-core/src/types/namespace/inherit.rs @@ -4,9 +4,12 @@ use crate::parse_internal; use crate::types::delegate_component::{EvalForEntry, EvaluatedForEntry}; use crate::types::ident::PathWithTypeArgs; +/// A namespace's inheritance from its parent. #[derive(Debug, Clone)] pub struct InheritNamespaceStatement { + /// The parent namespace. pub namespace: PathWithTypeArgs, + /// The local table's name. pub local_table_ident: Ident, } diff --git a/crates/macros/cgp-macro-core/src/types/namespace/table.rs b/crates/macros/cgp-macro-core/src/types/namespace/table.rs index 391c39923..b579fa02b 100644 --- a/crates/macros/cgp-macro-core/src/types/namespace/table.rs +++ b/crates/macros/cgp-macro-core/src/types/namespace/table.rs @@ -14,11 +14,17 @@ use crate::types::keyword::Keyword; use crate::types::keywords::New; use crate::types::namespace::{EvaluatedNamespaceTable, InheritNamespaceStatement}; +/// The parsed `cgp_namespace!` table. pub struct NamespaceTable { + /// The namespace's generic parameters. pub impl_generics: ImplGenerics, + /// The `new` keyword, when the namespace declares its struct. pub new: Option>, + /// The namespace's name and arguments. pub namespace: IdentWithTypeArgs, + /// The parent namespace, when the namespace inherits one. pub parent_namespace: Option<(Colon, PathWithTypeArgs)>, + /// The namespace's wiring entries. pub entries: DelegateEntries, } @@ -93,6 +99,7 @@ fn reject_self_inheritance( } impl NamespaceTable { + /// Builds the namespace trait's type with the table parameter. pub fn build_namespace_trait(&self) -> syn::Result { let mut namespace = self.namespace.clone(); @@ -102,6 +109,7 @@ impl NamespaceTable { Ok(namespace_trait) } + /// Builds the namespace trait, when the namespace declares one. pub fn build_item_trait(&self) -> syn::Result> { let namespace_trait = self.build_namespace_trait()?; @@ -126,6 +134,7 @@ impl NamespaceTable { Ok(item_trait) } + /// Builds the namespace trait's impls, one per entry. pub fn build_item_impls(&self) -> syn::Result> { let mut impl_generics = self.impl_generics.clone(); impl_generics.params.push(parse_internal!(__Table__)); @@ -147,6 +156,7 @@ impl NamespaceTable { Ok(item_impls) } + /// Builds the namespace's marker struct, when it declares one. pub fn build_namespace_struct(&self) -> syn::Result> { if self.new.is_none() { return Ok(None); @@ -168,6 +178,7 @@ impl NamespaceTable { Ok(Some(namespace_struct)) } + /// Builds the impl that inherits the parent namespace's entries. pub fn build_parent_namespace_impl(&self) -> syn::Result> { let Some((_, parent_namespace)) = &self.parent_namespace else { return Ok(None); @@ -200,6 +211,7 @@ impl NamespaceTable { Ok(Some(item_impl)) } + /// Evaluates the table into its generated items. pub fn eval(&self) -> syn::Result { let item_trait = self.build_item_trait()?; let mut item_impls = self.build_item_impls()?; diff --git a/crates/macros/cgp-macro-core/src/types/path/path_element.rs b/crates/macros/cgp-macro-core/src/types/path/path_element.rs index fdc387696..2c1316619 100644 --- a/crates/macros/cgp-macro-core/src/types/path/path_element.rs +++ b/crates/macros/cgp-macro-core/src/types/path/path_element.rs @@ -8,9 +8,12 @@ use crate::functions::parse_internal; use crate::traits::ToType; use crate::types::field::Symbol; +/// One segment of a type-level path. #[derive(Debug, Clone)] pub enum PathElement { + /// A type segment. Type(Type), + /// A symbol segment. Symbol(Symbol), } diff --git a/crates/macros/cgp-macro-core/src/types/path/path_element_with_generics.rs b/crates/macros/cgp-macro-core/src/types/path/path_element_with_generics.rs index 88a1546dc..8b0898912 100644 --- a/crates/macros/cgp-macro-core/src/types/path/path_element_with_generics.rs +++ b/crates/macros/cgp-macro-core/src/types/path/path_element_with_generics.rs @@ -3,9 +3,12 @@ use syn::parse::{Parse, ParseStream}; use crate::types::generics::ImplGenerics; use crate::types::path::PathElement; +/// A path element with its own generics. #[derive(Debug, Clone)] pub struct PathElementWithGenerics { + /// The element's generics. pub generics: ImplGenerics, + /// The element. pub element: PathElement, } diff --git a/crates/macros/cgp-macro-core/src/types/path/path_head.rs b/crates/macros/cgp-macro-core/src/types/path/path_head.rs index ac01e705d..78e71c5b0 100644 --- a/crates/macros/cgp-macro-core/src/types/path/path_head.rs +++ b/crates/macros/cgp-macro-core/src/types/path/path_head.rs @@ -6,15 +6,21 @@ use syn::{braced, bracketed}; use crate::types::generics::ImplGenerics; use crate::types::path::{PathElementWithGenerics, UniPath}; +/// A parsed path head, with its alternatives. #[derive(Debug, Clone)] pub enum PathHead { + /// A path element followed by the rest of the path. Type(Box, Box), + /// A brace group of alternative paths. Nested(Punctuated), + /// A bracket group of alternatives for one segment. Group(Punctuated, Box), + /// The end of the path. End, } impl PathHead { + /// Expands the alternatives into concrete paths. pub fn into_paths(&self) -> Vec<(ImplGenerics, UniPath)> { match self { Self::Type(path_element, tail) => { diff --git a/crates/macros/cgp-macro-core/src/types/path/path_head_or_type.rs b/crates/macros/cgp-macro-core/src/types/path/path_head_or_type.rs index 7ff473c62..6ac97e7f6 100644 --- a/crates/macros/cgp-macro-core/src/types/path/path_head_or_type.rs +++ b/crates/macros/cgp-macro-core/src/types/path/path_head_or_type.rs @@ -5,10 +5,13 @@ use syn::token::At; use crate::types::generics::ImplGenerics; use crate::types::path::PathHead; +/// A path head or a plain type. #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone)] pub enum PathHeadOrType { + /// A path head. PathHead(PathHead), + /// A plain type with its generics. Type(ImplGenerics, Type), } diff --git a/crates/macros/cgp-macro-core/src/types/path/prefix.rs b/crates/macros/cgp-macro-core/src/types/path/prefix.rs index 5d1b4268e..7234f445d 100644 --- a/crates/macros/cgp-macro-core/src/types/path/prefix.rs +++ b/crates/macros/cgp-macro-core/src/types/path/prefix.rs @@ -7,9 +7,12 @@ use syn::token::Dot; use crate::exports::PathCons; use crate::types::path::PathElement; +/// A path prefix with a suffix appended. #[derive(Debug, Clone)] pub struct PrefixPath { + /// The path's elements. pub elements: Punctuated, + /// The type appended after the elements. pub suffix: Type, } diff --git a/crates/macros/cgp-macro-core/src/types/path/unipath.rs b/crates/macros/cgp-macro-core/src/types/path/unipath.rs index b01552167..78da488f9 100644 --- a/crates/macros/cgp-macro-core/src/types/path/unipath.rs +++ b/crates/macros/cgp-macro-core/src/types/path/unipath.rs @@ -8,8 +8,10 @@ use syn::token::{At, Dot}; use crate::exports::{Nil, PathCons}; use crate::types::path::{PathElement, PrefixPath}; +/// A type-level path. #[derive(Debug, Clone, Default)] pub struct UniPath { + /// The path's elements. pub elements: Punctuated, } @@ -22,10 +24,12 @@ impl FromIterator for UniPath { } impl UniPath { + /// Appends a type to the path. pub fn append_type(&mut self, ty: Type) { self.elements.push(PathElement::Type(ty)); } + /// Appends a suffix type to the path. pub fn to_prefix(self, suffix: Type) -> PrefixPath { PrefixPath { elements: self.elements, diff --git a/crates/macros/cgp-macro-core/src/types/path/unipath_or_type.rs b/crates/macros/cgp-macro-core/src/types/path/unipath_or_type.rs index 80f4b7202..708ce95dc 100644 --- a/crates/macros/cgp-macro-core/src/types/path/unipath_or_type.rs +++ b/crates/macros/cgp-macro-core/src/types/path/unipath_or_type.rs @@ -6,8 +6,11 @@ use syn::token::At; use crate::types::path::UniPath; +/// A type-level path or a plain type. pub enum UniPathOrType { + /// A plain type. Type(Type), + /// A type-level path. Path(UniPath), } diff --git a/crates/macros/cgp-macro-core/src/types/product/product_expr.rs b/crates/macros/cgp-macro-core/src/types/product/product_expr.rs index e7ea5181c..a9fb9399a 100644 --- a/crates/macros/cgp-macro-core/src/types/product/product_expr.rs +++ b/crates/macros/cgp-macro-core/src/types/product/product_expr.rs @@ -10,12 +10,14 @@ use crate::functions::parse_internal; /// The value-level `product!` macro: a list of expression items that folds into a /// `Cons(..)`/`Nil` value expression. The type-level counterpart is `ProductType`. pub struct ProductExpr { + /// The entries. pub exprs: Punctuated, } impl ProductExpr { /// Fold the items right-to-left onto `Nil` with the `Cons` tuple-struct /// constructor, yielding a value expression (not a type). + /// Expands the list into nested `Cons` values. pub fn eval(&self) -> syn::Result { let mut out = quote!(#Nil); diff --git a/crates/macros/cgp-macro-core/src/types/product/product_type.rs b/crates/macros/cgp-macro-core/src/types/product/product_type.rs index 95dea299b..eb7caac14 100644 --- a/crates/macros/cgp-macro-core/src/types/product/product_type.rs +++ b/crates/macros/cgp-macro-core/src/types/product/product_type.rs @@ -7,11 +7,14 @@ use syn::token::Comma; use crate::exports::{Cons, Nil}; use crate::functions::parse_internal; +/// The parsed `Product!` list. pub struct ProductType { + /// The entries. pub types: Punctuated, } impl ProductType { + /// Expands the list into nested `Cons` types. pub fn eval(&self) -> syn::Result { let mut out = quote!(#Nil); diff --git a/crates/macros/cgp-macro-core/src/types/provider_impl.rs b/crates/macros/cgp-macro-core/src/types/provider_impl.rs index ab8bf1712..a549eb7ef 100644 --- a/crates/macros/cgp-macro-core/src/types/provider_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/provider_impl.rs @@ -10,6 +10,7 @@ use crate::types::cgp_provider::ProviderImplArgs; use crate::types::ident::PathWithTypeArgs; use crate::visitors::replace_provider_in_generics; +/// Derives the `IsProviderFor` impl for a provider impl. pub fn derive_is_provider_for( component_type: &Type, item_impl: &ItemImpl, @@ -21,12 +22,16 @@ pub fn derive_is_provider_for( .to_is_provider_for_impl() } +/// A list of provider impls. #[derive(Default)] pub struct ItemProviderImpls { + /// The provider impls. pub items: Vec, } impl ItemProviderImpls { + /// Generates every provider impl and its `IsProviderFor` impl. + /// Generates the provider impl and its `IsProviderFor` impl. pub fn to_item_impls(&self) -> syn::Result> { let mut item_impls = Vec::new(); @@ -38,17 +43,22 @@ impl ItemProviderImpls { } } +/// One provider impl and the component it implements. pub struct ItemProviderImpl { + /// The component's type. pub component_type: Type, + /// The provider impl. pub item_impl: ItemImpl, } impl ItemProviderImpl { + /// Generates the provider impl and its `IsProviderFor` impl. pub fn to_item_impls(&self) -> syn::Result> { let is_provider_impl = self.to_is_provider_for_impl()?; Ok(vec![self.item_impl.clone(), is_provider_impl]) } + /// Generates the `IsProviderFor` impl under the provider's bounds. pub fn to_is_provider_for_impl(&self) -> syn::Result { let component_type = &self.component_type; let item_impl = &self.item_impl; diff --git a/crates/macros/cgp-macro-core/src/types/shape/enum_type.rs b/crates/macros/cgp-macro-core/src/types/shape/enum_type.rs index 371b81f83..55218c8e3 100644 --- a/crates/macros/cgp-macro-core/src/types/shape/enum_type.rs +++ b/crates/macros/cgp-macro-core/src/types/shape/enum_type.rs @@ -16,12 +16,14 @@ use crate::types::cgp_data::variants_to_sum_type; /// As with [`StructType`](super::StructType), holding the derive's input form lets /// [`eval`](Self::eval) run the `#[derive(HasFields)]` encoder unchanged. pub struct EnumType { + /// The variants. pub variants: Punctuated, } impl EnumType { /// Encode the variants as the derive does: a sum of `Field` /// entries ending in `Void`, each payload encoded by the `Struct!` rules. + /// Expands the shape into a `Fields` type. pub fn eval(&self) -> syn::Result { variants_to_sum_type(&self.variants, &TokenStream::new()) } diff --git a/crates/macros/cgp-macro-core/src/types/shape/struct_type.rs b/crates/macros/cgp-macro-core/src/types/shape/struct_type.rs index 38a3b965d..f745f3348 100644 --- a/crates/macros/cgp-macro-core/src/types/shape/struct_type.rs +++ b/crates/macros/cgp-macro-core/src/types/shape/struct_type.rs @@ -11,6 +11,7 @@ use crate::types::cgp_data::item_fields_to_product_type; /// Holding the derive's own input form lets [`eval`](Self::eval) run the `#[derive(HasFields)]` /// encoder unchanged, so `Struct! { … }` is by construction the type a derived `Fields` is. pub struct StructType { + /// The fields. pub fields: Fields, } @@ -18,6 +19,7 @@ impl StructType { /// Encode the fields as the derive does: a product of `Field` entries, keyed by `Symbol!` /// for named fields and by `Index` for positional ones, with a one-field tuple body /// encoding to its bare type and an empty body to `Nil`. + /// Expands the shape into a `Fields` type. pub fn eval(&self) -> syn::Result { item_fields_to_product_type(&self.fields, &TokenStream::new()) } diff --git a/crates/macros/cgp-macro-core/src/types/sum.rs b/crates/macros/cgp-macro-core/src/types/sum.rs index b13e84324..e27329f60 100644 --- a/crates/macros/cgp-macro-core/src/types/sum.rs +++ b/crates/macros/cgp-macro-core/src/types/sum.rs @@ -7,11 +7,14 @@ use syn::token::Comma; use crate::exports::{Either, Void}; use crate::functions::parse_internal; +/// The parsed `Sum!` list. pub struct SumType { + /// The alternatives. pub types: Punctuated, } impl SumType { + /// Expands the list into nested `Either` types. pub fn eval(&self) -> syn::Result { let mut out = quote!(#Void); diff --git a/crates/macros/cgp-macro-core/src/visitors/collect_bare_aliases.rs b/crates/macros/cgp-macro-core/src/visitors/collect_bare_aliases.rs index fc8769931..db0f81c06 100644 --- a/crates/macros/cgp-macro-core/src/visitors/collect_bare_aliases.rs +++ b/crates/macros/cgp-macro-core/src/visitors/collect_bare_aliases.rs @@ -18,6 +18,7 @@ use crate::visitors::bare_alias_ident; /// its caret on the offending alias rather than on the whole macro block. #[derive(Default)] pub struct CollectBareAliases<'ast> { + /// The aliases found, in source order. pub idents: Vec<&'ast Ident>, } diff --git a/crates/macros/cgp-macro-core/src/visitors/remove_self_path.rs b/crates/macros/cgp-macro-core/src/visitors/remove_self_path.rs index 646f501a4..3e3b2ad03 100644 --- a/crates/macros/cgp-macro-core/src/visitors/remove_self_path.rs +++ b/crates/macros/cgp-macro-core/src/visitors/remove_self_path.rs @@ -1,7 +1,9 @@ use syn::visit_mut::{VisitMut, visit_type_mut}; use syn::{Ident, PathArguments, Type, TypePath}; +/// Removes a `Self::` prefix from the associated items the block declares. pub struct RemoveSelfPathVisitor<'a> { + /// The associated items to strip the prefix from. pub assoc_idents: &'a [Ident], } diff --git a/crates/macros/cgp-macro-core/src/visitors/replace_provider.rs b/crates/macros/cgp-macro-core/src/visitors/replace_provider.rs index 9a0a83521..ad06593d6 100644 --- a/crates/macros/cgp-macro-core/src/visitors/replace_provider.rs +++ b/crates/macros/cgp-macro-core/src/visitors/replace_provider.rs @@ -10,6 +10,7 @@ use syn::{ use crate::exports::IsProviderFor; +/// Replaces each provider parameter with its concrete type in the bounds. pub fn replace_provider_in_generics(provider_map: &BTreeMap, generics: &mut Generics) { let mut visitor = ReplaceProviderVisitor { provider_map }; visit_generics_mut(&mut visitor, generics); diff --git a/crates/macros/cgp-macro-core/src/visitors/replace_self/qualify_self_const.rs b/crates/macros/cgp-macro-core/src/visitors/replace_self/qualify_self_const.rs index 485c96c47..0b5423b09 100644 --- a/crates/macros/cgp-macro-core/src/visitors/replace_self/qualify_self_const.rs +++ b/crates/macros/cgp-macro-core/src/visitors/replace_self/qualify_self_const.rs @@ -9,6 +9,7 @@ use syn::{ExprPath, Ident, Item, Macro, parse_quote}; /// Once the block's `Self` is the provider, a bare `Self::CONST` is ambiguous: /// the consumer trait's blanket impl gives the provider the same const. pub struct QualifySelfConstVisitor<'a> { + /// The consts the block declares. pub local_consts: &'a Vec, /// The qualified self, `>`. pub qualified_self: &'a TokenStream, diff --git a/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_receiver.rs b/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_receiver.rs index d62d5626b..f05e15017 100644 --- a/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_receiver.rs +++ b/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_receiver.rs @@ -6,7 +6,9 @@ use syn::{FnArg, Item, Receiver, Signature, Type, parse_quote}; /// preserving the reference and mutability shape (`&self` → `ctx: &Context`, /// `&mut self` → `ctx: &mut Context`, `self` → `ctx: Context`). pub struct ReplaceSelfReceiverVisitor<'a> { + /// The identifier the receiver becomes. pub replaced_ident: &'a Ident, + /// The type the receiver becomes. pub replaced_type: &'a Type, } @@ -26,6 +28,7 @@ impl<'a> VisitMut for ReplaceSelfReceiverVisitor<'a> { } } +/// Rewrites one receiver into an explicit context parameter. pub fn replace_self_receiver( receiver: &mut Receiver, replaced_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_type.rs b/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_type.rs index 1564579a8..ae7c2378b 100644 --- a/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_type.rs +++ b/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_type.rs @@ -8,7 +8,9 @@ use syn::{Item, Macro, Path, Type}; /// skipping any `Self::Item` whose associated type or const is declared locally /// in the block, so the block's own associated items are left intact. pub struct ReplaceSelfTypeVisitor<'a> { + /// The type `Self` becomes. pub replaced_type: &'a Type, + /// The associated items to leave alone. pub skip_assoc_items: &'a Vec, } @@ -71,6 +73,7 @@ impl VisitMut for ReplaceSelfTypeVisitor<'_> { } } +/// Replaces `Self` in a macro body's tokens. pub fn replace_self_type_in_token_stream( stream: TokenStream, replaced_ident: TokenStream, diff --git a/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_value.rs b/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_value.rs index 62853753b..5736a2191 100644 --- a/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_value.rs +++ b/crates/macros/cgp-macro-core/src/visitors/replace_self/replace_self_value.rs @@ -8,6 +8,7 @@ use syn::{Expr, Ident, Item, Macro, Path}; /// at nested items (which introduce their own `self` and do not capture the /// outer one) and leaving `self::` module paths inside macro bodies intact. pub struct ReplaceSelfValueVisitor<'a> { + /// The identifier `self` becomes. pub replaced_ident: &'a Ident, } @@ -35,6 +36,7 @@ impl VisitMut for ReplaceSelfValueVisitor<'_> { } } +/// Replaces `self` in a macro body's tokens. pub fn replace_self_value_in_token_stream( stream: TokenStream, replaced_ident: &Ident, diff --git a/crates/macros/cgp-macro-core/src/visitors/self_assoc_type.rs b/crates/macros/cgp-macro-core/src/visitors/self_assoc_type.rs index a97fcb01c..201467a9f 100644 --- a/crates/macros/cgp-macro-core/src/visitors/self_assoc_type.rs +++ b/crates/macros/cgp-macro-core/src/visitors/self_assoc_type.rs @@ -5,6 +5,7 @@ use syn::token::Plus; use syn::visit_mut::{VisitMut, visit_type_mut, visit_type_param_bound_mut}; use syn::{Ident, TraitItemType, Type, TypeParamBound, parse_quote}; +/// Returns an associated type's bounds with `Self::Type` replaced by `Type`. pub fn get_bounds_and_replace_self_assoc_type( item_type: &TraitItemType, ) -> Punctuated { @@ -20,7 +21,9 @@ pub fn get_bounds_and_replace_self_assoc_type( bounds } +/// Replaces `Self::Type` with `Type` in a bound. pub struct ReplaceSelfAssocTypeVisitor { + /// The associated type's name. pub type_ident: Ident, } diff --git a/crates/macros/cgp-macro-core/src/visitors/substitute_abstract_type.rs b/crates/macros/cgp-macro-core/src/visitors/substitute_abstract_type.rs index f9f913f43..1b2c2847b 100644 --- a/crates/macros/cgp-macro-core/src/visitors/substitute_abstract_type.rs +++ b/crates/macros/cgp-macro-core/src/visitors/substitute_abstract_type.rs @@ -53,10 +53,12 @@ pub fn bare_alias_ident(ty: &Type) -> Option<&Ident> { /// has to revisit its own output to finish a nested import. `ground_specs` /// establishes the property by resolving each spec against its dependencies. pub struct SubstituteAbstractTypes<'a> { + /// The imported abstract types. pub specs: &'a [UseTypeAttribute], } impl<'a> SubstituteAbstractTypes<'a> { + /// Creates a visitor over the given imports. pub fn new(specs: &'a [UseTypeAttribute]) -> Self { Self { specs } } diff --git a/crates/macros/cgp-macro-extra-core/src/lib.rs b/crates/macros/cgp-macro-extra-core/src/lib.rs index f9a7d9b42..61ca0ed46 100644 --- a/crates/macros/cgp-macro-extra-core/src/lib.rs +++ b/crates/macros/cgp-macro-extra-core/src/lib.rs @@ -2,8 +2,13 @@ //! visitors. //! //! See [`#[cgp_computer]`](https://contextgeneric.dev/docs/reference/macros/cgp_computer) and [`#[cgp_auto_dispatch]`](https://contextgeneric.dev/docs/reference/macros/cgp_auto_dispatch) for the macros it builds. +#![warn(missing_docs)] +/// The re-exports the macro crates use. pub mod exports; +/// The shared parsing and code-generation helpers. pub mod functions; +/// The AST types for the extra macros. pub mod types; +/// The visitors that rewrite the parsed items. pub mod visitors; diff --git a/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/item.rs b/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/item.rs index 4f6d9d97e..d3964a7c6 100644 --- a/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/item.rs +++ b/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/item.rs @@ -5,6 +5,7 @@ use crate::types::cgp_auto_dispatch::{DispatchMethod, PreprocessedCgpAutoDispatc /// Raw input stage: the annotated trait. First stage of the /// `#[cgp_auto_dispatch]` pipeline. pub struct ItemCgpAutoDispatch { + /// The annotated trait. pub item_trait: ItemTrait, } diff --git a/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/method.rs b/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/method.rs index c7d74625b..09a15a175 100644 --- a/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/method.rs +++ b/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/method.rs @@ -24,8 +24,11 @@ use crate::visitors::{ElaborateElidedLifetimes, collect_lifetimes}; /// How a dispatch method takes `self`, with the lifetime a borrowed receiver /// carries: the one the method names, or the reserved `'__a__` when elided. pub enum DispatchReceiver { + /// A by-value `self`. Owned, + /// A shared borrow of `self`. Ref(Lifetime), + /// A mutable borrow of `self`. Mut(Lifetime), } @@ -38,10 +41,12 @@ pub enum DispatchReceiver { /// and an elided output lifetime is the receiver's, or, for a by-value `self`, /// the single lifetime the arguments use. pub struct DispatchMethod { + /// The trait method. pub method: TraitItemFn, /// The per-variant computer's name: `Compute` plus the method name in /// PascalCase. pub computer_ident: Ident, + /// How the method takes `self`. pub receiver: DispatchReceiver, /// The argument types after the receiver, with elided lifetimes named. pub arg_types: Vec, diff --git a/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/preprocessed.rs b/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/preprocessed.rs index 92c02ea33..255017761 100644 --- a/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/preprocessed.rs +++ b/crates/macros/cgp-macro-extra-core/src/types/cgp_auto_dispatch/preprocessed.rs @@ -8,7 +8,9 @@ use crate::types::cgp_auto_dispatch::{DispatchMethod, EvaluatedCgpAutoDispatch}; /// The checked `#[cgp_auto_dispatch]` input: the trait and one /// [`DispatchMethod`] per method. pub struct PreprocessedCgpAutoDispatch { + /// The annotated trait. pub item_trait: ItemTrait, + /// One entry per method. pub methods: Vec, } diff --git a/crates/macros/cgp-macro-extra-core/src/types/cgp_computer/item.rs b/crates/macros/cgp-macro-extra-core/src/types/cgp_computer/item.rs index 4d835fa72..b784b0af0 100644 --- a/crates/macros/cgp-macro-extra-core/src/types/cgp_computer/item.rs +++ b/crates/macros/cgp-macro-extra-core/src/types/cgp_computer/item.rs @@ -10,7 +10,9 @@ use crate::visitors::find_impl_trait; /// Raw input stage: the optional provider name from the attribute and the /// annotated function. First stage of the `#[cgp_computer]` pipeline. pub struct ItemCgpComputer { + /// The provider name from the attribute, if given. pub ident: Option, + /// The annotated function. pub item_fn: ItemFn, } diff --git a/crates/macros/cgp-macro-extra-core/src/types/cgp_computer/preprocessed.rs b/crates/macros/cgp-macro-extra-core/src/types/cgp_computer/preprocessed.rs index 89abc7bf8..13323caa4 100644 --- a/crates/macros/cgp-macro-extra-core/src/types/cgp_computer/preprocessed.rs +++ b/crates/macros/cgp-macro-extra-core/src/types/cgp_computer/preprocessed.rs @@ -19,10 +19,15 @@ use crate::types::handler_fn::EvaluatedHandlerFn; /// its inputs rebound as `arg_0, arg_1, …`, its output type, and the two facts /// that choose the expansion. pub struct PreprocessedCgpComputer { + /// The resolved provider name. pub provider_ident: Ident, + /// The annotated function. pub item_fn: ItemFn, + /// The function's inputs, rebound as `arg_0`, `arg_1`, and so on. pub input_idents: Punctuated, + /// The function's input types. pub input_types: Punctuated, + /// The function's output type. pub output: Type, /// An `async` function implements `AsyncComputer` rather than `Computer`. pub is_async: bool, diff --git a/crates/macros/cgp-macro-extra-core/src/types/cgp_producer/item.rs b/crates/macros/cgp-macro-extra-core/src/types/cgp_producer/item.rs index eef691f4f..fc976713a 100644 --- a/crates/macros/cgp-macro-extra-core/src/types/cgp_producer/item.rs +++ b/crates/macros/cgp-macro-extra-core/src/types/cgp_producer/item.rs @@ -7,7 +7,9 @@ use crate::visitors::find_impl_trait; /// Raw input stage: the optional provider name from the attribute and the /// annotated function. First stage of the `#[cgp_producer]` pipeline. pub struct ItemCgpProducer { + /// The provider name from the attribute, if given. pub ident: Option, + /// The annotated function. pub item_fn: ItemFn, } diff --git a/crates/macros/cgp-macro-extra-core/src/types/cgp_producer/preprocessed.rs b/crates/macros/cgp-macro-extra-core/src/types/cgp_producer/preprocessed.rs index 264ed8f54..3e8047455 100644 --- a/crates/macros/cgp-macro-extra-core/src/types/cgp_producer/preprocessed.rs +++ b/crates/macros/cgp-macro-extra-core/src/types/cgp_producer/preprocessed.rs @@ -15,8 +15,11 @@ use crate::types::handler_fn::EvaluatedHandlerFn; /// The validated `#[cgp_producer]` input: the resolved provider name, the /// function, and its output type. pub struct PreprocessedCgpProducer { + /// The resolved provider name. pub provider_ident: Ident, + /// The annotated function. pub item_fn: ItemFn, + /// The function's output type. pub output: Type, } diff --git a/crates/macros/cgp-macro-extra-core/src/types/mod.rs b/crates/macros/cgp-macro-extra-core/src/types/mod.rs index ea9668e8d..1186af62d 100644 --- a/crates/macros/cgp-macro-extra-core/src/types/mod.rs +++ b/crates/macros/cgp-macro-extra-core/src/types/mod.rs @@ -1,4 +1,8 @@ +/// The AST for `#[cgp_auto_dispatch]`. pub mod cgp_auto_dispatch; +/// The AST for `#[cgp_computer]`. pub mod cgp_computer; +/// The AST for `#[cgp_producer]`. pub mod cgp_producer; +/// The shared handler-function lowering. pub mod handler_fn; diff --git a/crates/macros/cgp-macro-extra-lib/src/cgp_auto_dispatch.rs b/crates/macros/cgp-macro-extra-lib/src/cgp_auto_dispatch.rs index d5c27cd13..90191ff92 100644 --- a/crates/macros/cgp-macro-extra-lib/src/cgp_auto_dispatch.rs +++ b/crates/macros/cgp-macro-extra-lib/src/cgp_auto_dispatch.rs @@ -5,6 +5,9 @@ use syn::{Error, ItemTrait, parse2}; use crate::handler_fn::lower_handler_fn; +/// Generate a handler that dispatches over an extensible-data input from a per-type trait, routing each variant to its own implementation. +/// +/// See [`cgp_auto_dispatch`](https://contextgeneric.dev/docs/reference/macros/cgp_auto_dispatch). pub fn cgp_auto_dispatch(attr: TokenStream, body: TokenStream) -> syn::Result { if !attr.is_empty() { return Err(Error::new_spanned( diff --git a/crates/macros/cgp-macro-extra-lib/src/cgp_computer.rs b/crates/macros/cgp-macro-extra-lib/src/cgp_computer.rs index 8233c5f52..e09891db2 100644 --- a/crates/macros/cgp-macro-extra-lib/src/cgp_computer.rs +++ b/crates/macros/cgp-macro-extra-lib/src/cgp_computer.rs @@ -4,6 +4,9 @@ use syn::{Ident, ItemFn, parse2}; use crate::handler_fn::lower_handler_fn; +/// Define a Computer provider from a plain Rust function, with the promotion tables that let one function answer the rest of the handler family. +/// +/// See [`cgp_computer`](https://contextgeneric.dev/docs/reference/macros/cgp_computer). pub fn cgp_computer(attr: TokenStream, body: TokenStream) -> syn::Result { let item_fn: ItemFn = parse2(body)?; diff --git a/crates/macros/cgp-macro-extra-lib/src/cgp_producer.rs b/crates/macros/cgp-macro-extra-lib/src/cgp_producer.rs index 713cbb273..b86b6206a 100644 --- a/crates/macros/cgp-macro-extra-lib/src/cgp_producer.rs +++ b/crates/macros/cgp-macro-extra-lib/src/cgp_producer.rs @@ -4,6 +4,9 @@ use syn::{Ident, ItemFn, parse2}; use crate::handler_fn::lower_handler_fn; +/// Define a Producer provider from an input-free function, for a computation that takes only a context and a code tag. +/// +/// See [`cgp_producer`](https://contextgeneric.dev/docs/reference/macros/cgp_producer). pub fn cgp_producer(attr: TokenStream, body: TokenStream) -> syn::Result { let item_fn: ItemFn = parse2(body)?; diff --git a/crates/macros/cgp-macro-extra-lib/src/lib.rs b/crates/macros/cgp-macro-extra-lib/src/lib.rs index 002e81f26..24859fa5f 100644 --- a/crates/macros/cgp-macro-extra-lib/src/lib.rs +++ b/crates/macros/cgp-macro-extra-lib/src/lib.rs @@ -2,6 +2,7 @@ //! types. //! //! See [`#[cgp_computer]`](https://contextgeneric.dev/docs/reference/macros/cgp_computer), [`#[cgp_producer]`](https://contextgeneric.dev/docs/reference/macros/cgp_producer), and [`#[cgp_auto_dispatch]`](https://contextgeneric.dev/docs/reference/macros/cgp_auto_dispatch). +#![warn(missing_docs)] mod cgp_auto_dispatch; mod cgp_computer; diff --git a/crates/macros/cgp-macro-extra/src/lib.rs b/crates/macros/cgp-macro-extra/src/lib.rs index 739ca8fdc..ecc67c3eb 100644 --- a/crates/macros/cgp-macro-extra/src/lib.rs +++ b/crates/macros/cgp-macro-extra/src/lib.rs @@ -3,6 +3,7 @@ //! and dispatch a trait over an enum. //! //! See [`#[cgp_computer]`](https://contextgeneric.dev/docs/reference/macros/cgp_computer), [`#[cgp_producer]`](https://contextgeneric.dev/docs/reference/macros/cgp_producer), and [`#[cgp_auto_dispatch]`](https://contextgeneric.dev/docs/reference/macros/cgp_auto_dispatch). +#![warn(missing_docs)] use proc_macro::TokenStream; diff --git a/crates/macros/cgp-macro-lib/src/blanket_trait.rs b/crates/macros/cgp-macro-lib/src/blanket_trait.rs index fd1ce2d5c..875df5b31 100644 --- a/crates/macros/cgp-macro-lib/src/blanket_trait.rs +++ b/crates/macros/cgp-macro-lib/src/blanket_trait.rs @@ -3,6 +3,9 @@ use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::{Ident, ItemTrait, parse2}; +/// Generate a blanket implementation from a Rust trait with default methods and supertrait dependencies. +/// +/// See [`blanket_trait`](https://contextgeneric.dev/docs/reference/macros/blanket_trait). pub fn blanket_trait(attr: TokenStream, body: TokenStream) -> syn::Result { let context_ident: Ident = if attr.is_empty() { Ident::new("__Context__", Span::call_site()) diff --git a/crates/macros/cgp-macro-lib/src/cgp_auto_getter.rs b/crates/macros/cgp-macro-lib/src/cgp_auto_getter.rs index 3d9a05d86..569d39f77 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_auto_getter.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_auto_getter.rs @@ -3,6 +3,9 @@ use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::{Error, ItemTrait}; +/// Define a getter as a blanket implementation over HasField, keyed by the method name, for reading a field from any context that has one. +/// +/// See [`cgp_auto_getter`](https://contextgeneric.dev/docs/reference/macros/cgp_auto_getter). pub fn cgp_auto_getter(attr: TokenStream, body: TokenStream) -> syn::Result { if !attr.is_empty() { return Err(Error::new( diff --git a/crates/macros/cgp-macro-lib/src/cgp_data.rs b/crates/macros/cgp-macro-lib/src/cgp_data.rs index 47a31d442..a2bf6da60 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_data.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_data.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::parse2; +/// Generate structural access and the incremental building and extraction operations for a struct or enum, as the umbrella over the narrower derives. +/// +/// See [`CgpData`](https://contextgeneric.dev/docs/reference/derives/derive_cgp_data). pub fn derive_cgp_data(body: TokenStream) -> syn::Result { let data: ItemCgpData = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_fn.rs b/crates/macros/cgp-macro-lib/src/cgp_fn.rs index ec142c9bf..16c1f08be 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_fn.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_fn.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{Ident, ItemFn, parse2}; +/// Turn a plain Rust function into a trait with a single blanket implementation, so it runs on any context that supplies the fields it needs. +/// +/// See [`cgp_fn`](https://contextgeneric.dev/docs/reference/macros/cgp_fn). pub fn cgp_fn(attr: TokenStream, body: TokenStream) -> syn::Result { let item_fn: ItemFn = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_getter.rs b/crates/macros/cgp-macro-lib/src/cgp_getter.rs index da38990ef..4c34ee0b4 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_getter.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_getter.rs @@ -4,6 +4,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{Ident, ItemTrait, parse2}; +/// Define a getter as a full CGP component, so the field it reads is chosen when a context is wired rather than fixed to the method name. +/// +/// See [`cgp_getter`](https://contextgeneric.dev/docs/reference/macros/cgp_getter). pub fn cgp_getter(attr: TokenStream, body: TokenStream) -> syn::Result { let mut raw_args: CgpComponentRawArgs = parse2(attr.clone())?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_impl.rs b/crates/macros/cgp-macro-lib/src/cgp_impl.rs index 7c2a24310..da9497315 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_impl.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_impl.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemImpl, parse2}; +/// Write a CGP provider in ordinary consumer-trait shape, keeping self, Self and the method signatures you already know, instead of the inside-out form. +/// +/// See [`cgp_impl`](https://contextgeneric.dev/docs/reference/macros/cgp_impl). pub fn cgp_impl(attr: TokenStream, body: TokenStream) -> syn::Result { let args: ImplArgs = parse2(attr)?; let item_impl: ItemImpl = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_namespace.rs b/crates/macros/cgp-macro-lib/src/cgp_namespace.rs index 4f5905209..aea4f3cd5 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_namespace.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_namespace.rs @@ -4,6 +4,9 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; +/// Define a reusable, inheritable wiring table that many contexts can join, so a configuration stays short as the component count grows. +/// +/// See [`cgp_namespace`](https://contextgeneric.dev/docs/reference/macros/cgp_namespace). pub fn cgp_namespace(body: TokenStream) -> syn::Result { let namespace_table: NamespaceTable = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_new_provider.rs b/crates/macros/cgp-macro-lib/src/cgp_new_provider.rs index 81c15f632..f50df867d 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_new_provider.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_new_provider.rs @@ -4,6 +4,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemImpl, parse2}; +/// Implement a provider trait directly, in the inside-out shape the ergonomic macros desugar to, with or without declaring the provider struct. +/// +/// See [`cgp_provider`](https://contextgeneric.dev/docs/reference/macros/cgp_provider). pub fn cgp_new_provider(attr: TokenStream, body: TokenStream) -> syn::Result { let item_impl: ItemImpl = parse2(body)?; let mut args: ProviderArgs = parse2(attr)?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_provider.rs b/crates/macros/cgp-macro-lib/src/cgp_provider.rs index d541ca399..1558f6477 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_provider.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_provider.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemImpl, parse2}; +/// Implement a provider trait directly, in the inside-out shape the ergonomic macros desugar to, with or without declaring the provider struct. +/// +/// See [`cgp_provider`](https://contextgeneric.dev/docs/reference/macros/cgp_provider). pub fn cgp_provider(attr: TokenStream, body: TokenStream) -> syn::Result { let item_impl: ItemImpl = parse2(body)?; let args: ProviderArgs = parse2(attr)?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_record.rs b/crates/macros/cgp-macro-lib/src/cgp_record.rs index a1969b360..3e493ba8a 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_record.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_record.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::parse2; +/// Generate field access, a structural representation, and a builder for a struct, as the record half of the extensible-data derives. +/// +/// See [`CgpRecord`](https://contextgeneric.dev/docs/reference/derives/derive_cgp_record). pub fn derive_cgp_record(body: TokenStream) -> syn::Result { let record: ItemCgpRecord = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_type.rs b/crates/macros/cgp-macro-lib/src/cgp_type.rs index cef60003d..edd4817a7 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_type.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_type.rs @@ -4,6 +4,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{Ident, ItemTrait, parse2}; +/// Define an abstract-type component whose concrete type each context chooses for itself, for an error type, a runtime, or any type generic code has to name. +/// +/// See [`cgp_type`](https://contextgeneric.dev/docs/reference/macros/cgp_type). pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> syn::Result { let mut raw_args: CgpComponentRawArgs = parse2(attrs.clone())?; diff --git a/crates/macros/cgp-macro-lib/src/cgp_variant.rs b/crates/macros/cgp-macro-lib/src/cgp_variant.rs index 802d24475..f249e496d 100644 --- a/crates/macros/cgp-macro-lib/src/cgp_variant.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_variant.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::parse2; +/// Generate a structural representation, constructors, and an extractor for an enum, as the variant half of the extensible-data derives. +/// +/// See [`CgpVariant`](https://contextgeneric.dev/docs/reference/derives/derive_cgp_variant). pub fn derive_cgp_variant(body: TokenStream) -> syn::Result { let variant: ItemCgpVariant = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/check_components.rs b/crates/macros/cgp-macro-lib/src/check_components.rs index 4835194df..94047ffe2 100644 --- a/crates/macros/cgp-macro-lib/src/check_components.rs +++ b/crates/macros/cgp-macro-lib/src/check_components.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::parse2; +/// Assert at compile time that a context can use the components it wires, so a missing dependency fails at the assertion rather than at a distant call site. +/// +/// See [`check_components`](https://contextgeneric.dev/docs/reference/macros/check_components). pub fn check_components(body: TokenStream) -> syn::Result { let tables: CheckComponentsTables = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/delegate_and_check_components.rs b/crates/macros/cgp-macro-lib/src/delegate_and_check_components.rs index 8bba31bc5..514333e33 100644 --- a/crates/macros/cgp-macro-lib/src/delegate_and_check_components.rs +++ b/crates/macros/cgp-macro-lib/src/delegate_and_check_components.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::parse2; +/// Wire a context and check that wiring in one macro, for getting started and for plain Component: Provider tables. Wrong for an aggregate provider. +/// +/// See [`delegate_and_check_components`](https://contextgeneric.dev/docs/reference/macros/delegate_and_check_components). pub fn delegate_and_check_components(body: TokenStream) -> syn::Result { let item: ItemDelegateAndCheckComponents = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/delegate_components.rs b/crates/macros/cgp-macro-lib/src/delegate_components.rs index 43dffa5af..4112578b3 100644 --- a/crates/macros/cgp-macro-lib/src/delegate_components.rs +++ b/crates/macros/cgp-macro-lib/src/delegate_components.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; +/// Build a context's wiring table, naming the provider that implements each component, plus the operators, path keys and statements its body accepts. +/// +/// See [`delegate_components`](https://contextgeneric.dev/docs/reference/macros/delegate_components). pub fn delegate_components(body: TokenStream) -> syn::Result { let table: DelegateTable = parse2(body.clone())?; diff --git a/crates/macros/cgp-macro-lib/src/derive_build_field.rs b/crates/macros/cgp-macro-lib/src/derive_build_field.rs index cc0ee473b..dbf3ae4c2 100644 --- a/crates/macros/cgp-macro-lib/src/derive_build_field.rs +++ b/crates/macros/cgp-macro-lib/src/derive_build_field.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemStruct, parse2}; +/// Generate a builder that tracks in its own type which fields of a struct have been supplied, so an incomplete record cannot be finalized. +/// +/// See [`BuildField`](https://contextgeneric.dev/docs/reference/derives/derive_build_field). pub fn derive_build_field(body: TokenStream) -> syn::Result { let item_struct: ItemStruct = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/derive_extract_field.rs b/crates/macros/cgp-macro-lib/src/derive_extract_field.rs index fc74fe9ca..a2ab8ea59 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extract_field.rs +++ b/crates/macros/cgp-macro-lib/src/derive_extract_field.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemEnum, parse2}; +/// Generate an extractor that tracks in its own type which variants of an enum remain, so exhaustiveness is checked without a wildcard arm. +/// +/// See [`ExtractField`](https://contextgeneric.dev/docs/reference/derives/derive_extract_field). pub fn derive_extract_field(body: TokenStream) -> syn::Result { let item_enum: ItemEnum = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/derive_from_variant.rs b/crates/macros/cgp-macro-lib/src/derive_from_variant.rs index 46ac7d480..46a8c1097 100644 --- a/crates/macros/cgp-macro-lib/src/derive_from_variant.rs +++ b/crates/macros/cgp-macro-lib/src/derive_from_variant.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemEnum, parse2}; +/// Let generic code construct an enum variant selected by a type-level tag, without naming the variant or the enum. +/// +/// See [`FromVariant`](https://contextgeneric.dev/docs/reference/derives/derive_from_variant). pub fn derive_from_variant(body: TokenStream) -> syn::Result { let item_enum: ItemEnum = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_field.rs b/crates/macros/cgp-macro-lib/src/derive_has_field.rs index 72116fbcc..f4fb8e952 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_field.rs +++ b/crates/macros/cgp-macro-lib/src/derive_has_field.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::ItemStruct; +/// Generate shared and mutable accessors for every field of a struct, keyed by type-level tags, which is what lets an implicit argument find a field. +/// +/// See [`HasField`](https://contextgeneric.dev/docs/reference/derives/derive_has_field). pub fn derive_has_field(input: TokenStream) -> syn::Result { let item_struct: ItemStruct = syn::parse2(input)?; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields.rs b/crates/macros/cgp-macro-lib/src/derive_has_fields.rs index 46f621861..d5fec89ab 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields.rs +++ b/crates/macros/cgp-macro-lib/src/derive_has_fields.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{Error, Item, parse2}; +/// Generate a structural representation of a struct or enum and the conversions to and from it, exposing its whole field or variant list to generic code. +/// +/// See [`HasFields`](https://contextgeneric.dev/docs/reference/derives/derive_has_fields). pub fn derive_has_fields(body: TokenStream) -> syn::Result { let item: Item = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/enum_type.rs b/crates/macros/cgp-macro-lib/src/enum_type.rs index 75c704183..823c5056a 100644 --- a/crates/macros/cgp-macro-lib/src/enum_type.rs +++ b/crates/macros/cgp-macro-lib/src/enum_type.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; +/// The type-level shape of an enum, written as the body of an enum declaration. +/// +/// See [`Enum`](https://contextgeneric.dev/docs/reference/macros/enum). #[allow(non_snake_case)] pub fn Enum(body: TokenStream) -> syn::Result { let enum_type: EnumType = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/lib.rs b/crates/macros/cgp-macro-lib/src/lib.rs index 318c6e166..294c15000 100644 --- a/crates/macros/cgp-macro-lib/src/lib.rs +++ b/crates/macros/cgp-macro-lib/src/lib.rs @@ -1,6 +1,7 @@ //! This crate implements CGP's procedural macros, one module per macro. //! //! See [`#[cgp_component]`](https://contextgeneric.dev/docs/reference/macros/cgp_component), [`#[cgp_impl]`](https://contextgeneric.dev/docs/reference/macros/cgp_impl), and [`delegate_components!`](https://contextgeneric.dev/docs/reference/macros/delegate_components). +#![warn(missing_docs)] mod blanket_trait; mod cgp_auto_getter; diff --git a/crates/macros/cgp-macro-lib/src/path.rs b/crates/macros/cgp-macro-lib/src/path.rs index b040e5b6f..b74360d22 100644 --- a/crates/macros/cgp-macro-lib/src/path.rs +++ b/crates/macros/cgp-macro-lib/src/path.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; +/// A type-level path, used by CGP namespaces and by component lookups that are redirected along one. +/// +/// See [`Path`](https://contextgeneric.dev/docs/reference/macros/path). #[allow(non_snake_case)] pub fn Path(body: TokenStream) -> syn::Result { let unipath: UniPath = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/product.rs b/crates/macros/cgp-macro-lib/src/product.rs index 54a2ba838..99fa4f320 100644 --- a/crates/macros/cgp-macro-lib/src/product.rs +++ b/crates/macros/cgp-macro-lib/src/product.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; +/// A type-level list and its value-level counterpart, used for the field lists of a record and for handler pipelines. +/// +/// See [`Product`](https://contextgeneric.dev/docs/reference/macros/product). #[allow(non_snake_case)] pub fn Product(body: TokenStream) -> syn::Result { let product_type: ProductType = parse2(body)?; @@ -12,6 +15,9 @@ pub fn Product(body: TokenStream) -> syn::Result { Ok(evaluated.to_token_stream()) } +/// A type-level list and its value-level counterpart, used for the field lists of a record and for handler pipelines. +/// +/// See [`product`](https://contextgeneric.dev/docs/reference/macros/product). pub fn product(body: TokenStream) -> syn::Result { let product_expr: ProductExpr = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/struct_type.rs b/crates/macros/cgp-macro-lib/src/struct_type.rs index 7bd6338ef..0bd11ebf1 100644 --- a/crates/macros/cgp-macro-lib/src/struct_type.rs +++ b/crates/macros/cgp-macro-lib/src/struct_type.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; +/// The type-level shape of a struct, written as the body of a struct declaration. +/// +/// See [`Struct`](https://contextgeneric.dev/docs/reference/macros/struct). #[allow(non_snake_case)] pub fn Struct(body: TokenStream) -> syn::Result { let struct_type: StructType = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/sum.rs b/crates/macros/cgp-macro-lib/src/sum.rs index b8ca75ec8..9a56b268d 100644 --- a/crates/macros/cgp-macro-lib/src/sum.rs +++ b/crates/macros/cgp-macro-lib/src/sum.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; +/// A type-level sum, the dual of Product!, used for the variant lists of an extensible enum. +/// +/// See [`Sum`](https://contextgeneric.dev/docs/reference/macros/sum). #[allow(non_snake_case)] pub fn Sum(body: TokenStream) -> syn::Result { let sum_type: SumType = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/symbol.rs b/crates/macros/cgp-macro-lib/src/symbol.rs index ef86bf9c5..1bad4cd99 100644 --- a/crates/macros/cgp-macro-lib/src/symbol.rs +++ b/crates/macros/cgp-macro-lib/src/symbol.rs @@ -3,6 +3,9 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; +/// A type-level string, used as the tag that names a struct field in CGP's field-access traits. +/// +/// See [`Symbol`](https://contextgeneric.dev/docs/reference/macros/symbol). #[allow(non_snake_case)] pub fn Symbol(body: TokenStream) -> syn::Result { let symbol: Symbol = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_blanket_trait.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_blanket_trait.rs index 63121f006..3215b5efd 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_blanket_trait.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_blanket_trait.rs @@ -5,6 +5,7 @@ use syn::{ItemTrait, parse2}; use crate::keywords::BlanketTrait; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `blanket_trait`. pub fn snapshot_blanket_trait(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_dispatch.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_dispatch.rs index 4ed02c09c..65316370e 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_dispatch.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_dispatch.rs @@ -5,6 +5,7 @@ use syn::{ItemTrait, parse2}; use crate::keywords::CgpAutoDispatch; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_auto_dispatch`. pub fn snapshot_cgp_auto_dispatch(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs index 0225408c7..8214f0096 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs @@ -5,6 +5,7 @@ use syn::{ItemTrait, parse2}; use crate::keywords::CgpAutoGetter; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_auto_getter`. pub fn snapshot_cgp_auto_getter(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs index 36b74092a..dff68c2e6 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs @@ -5,6 +5,7 @@ use syn::{ItemTrait, parse2}; use crate::keywords::CgpComponent; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_component`. pub fn snapshot_cgp_component(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_computer.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_computer.rs index c50931fc0..a4cd81ff8 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_computer.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_computer.rs @@ -5,6 +5,7 @@ use syn::{ItemFn, parse2}; use crate::keywords::CgpComputer; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_computer`. pub fn snapshot_cgp_computer(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs index 68fe60024..8058f210c 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs @@ -5,6 +5,7 @@ use syn::{ItemFn, parse2}; use crate::keywords::CgpFn; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_fn`. pub fn snapshot_cgp_fn(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs index bc2a615ba..f973026f8 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs @@ -5,6 +5,7 @@ use syn::{ItemTrait, parse2}; use crate::keywords::CgpGetter; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_getter`. pub fn snapshot_cgp_getter(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs index 6711cad76..87bb4b4ad 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs @@ -5,6 +5,7 @@ use syn::{ItemImpl, parse2}; use crate::keywords::CgpImpl; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_impl`. pub fn snapshot_cgp_impl(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs index 82e1870f4..bc0d0874d 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs @@ -4,6 +4,7 @@ use syn::parse2; use crate::keywords::CgpNamespace; use crate::types::StatementMacroSnapshot; +/// Snapshots the expansion of `cgp_namespace`. pub fn snapshot_cgp_namespace(body: TokenStream) -> syn::Result { let item: StatementMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_new_provider.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_new_provider.rs index 2b8e97c0d..2aec73480 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_new_provider.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_new_provider.rs @@ -5,6 +5,7 @@ use syn::{ItemImpl, parse2}; use crate::keywords::CgpNewProvider; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_new_provider`. pub fn snapshot_cgp_new_provider(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_producer.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_producer.rs index 78a030fe3..f2ec73f52 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_producer.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_producer.rs @@ -5,6 +5,7 @@ use syn::{ItemFn, parse2}; use crate::keywords::CgpProducer; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_producer`. pub fn snapshot_cgp_producer(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_provider.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_provider.rs index 43fc0937b..aef353880 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_provider.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_provider.rs @@ -5,6 +5,7 @@ use syn::{ItemImpl, parse2}; use crate::keywords::CgpProvider; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_provider`. pub fn snapshot_cgp_provider(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs index 1f09cecd9..57b575a41 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs @@ -5,6 +5,7 @@ use syn::{ItemTrait, parse2}; use crate::keywords::CgpType; use crate::types::AttributeMacroSnapshot; +/// Snapshots the expansion of `cgp_type`. pub fn snapshot_cgp_type(body: TokenStream) -> syn::Result { let item: AttributeMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs index f60047fe9..5ee1a92a3 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs @@ -4,6 +4,7 @@ use syn::parse2; use crate::keywords::CheckComponents; use crate::types::StatementMacroSnapshot; +/// Snapshots the expansion of `check_components`. pub fn snapshot_check_components(body: TokenStream) -> syn::Result { let item: StatementMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs index 92f2c7482..0de9c97c0 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs @@ -4,6 +4,7 @@ use syn::parse2; use crate::keywords::DelegateAndCheckComponents; use crate::types::StatementMacroSnapshot; +/// Snapshots the expansion of `delegate_and_check_components`. pub fn snapshot_delegate_and_check_components(body: TokenStream) -> syn::Result { let item: StatementMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs index 52048f92f..960832b5b 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs @@ -4,6 +4,7 @@ use syn::parse2; use crate::keywords::DelegateComponents; use crate::types::StatementMacroSnapshot; +/// Snapshots the expansion of `delegate_components`. pub fn snapshot_delegate_components(body: TokenStream) -> syn::Result { let item: StatementMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_build_field.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_build_field.rs index bdf25675e..d7e37c633 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_build_field.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_build_field.rs @@ -5,6 +5,7 @@ use syn::{ItemStruct, parse2}; use crate::keywords::BuildField; use crate::types::DeriveMacroSnapshot; +/// Snapshots the expansion of `derive_build_field`. pub fn snapshot_derive_build_field(body: TokenStream) -> syn::Result { let item: DeriveMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_cgp_data.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_cgp_data.rs index 71f2881c0..64103f80a 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_cgp_data.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_cgp_data.rs @@ -5,6 +5,7 @@ use syn::{Item, parse2}; use crate::keywords::CgpData; use crate::types::DeriveMacroSnapshot; +/// Snapshots the expansion of `derive_cgp_data`. pub fn snapshot_derive_cgp_data(body: TokenStream) -> syn::Result { let item: DeriveMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_extract_field.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_extract_field.rs index df263ed61..9d9d08846 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_extract_field.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_extract_field.rs @@ -5,6 +5,7 @@ use syn::{ItemEnum, parse2}; use crate::keywords::ExtractField; use crate::types::DeriveMacroSnapshot; +/// Snapshots the expansion of `derive_extract_field`. pub fn snapshot_derive_extract_field(body: TokenStream) -> syn::Result { let item: DeriveMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_from_variant.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_from_variant.rs index aab6ef9a0..6c6d88d83 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_from_variant.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_from_variant.rs @@ -5,6 +5,7 @@ use syn::{ItemEnum, parse2}; use crate::keywords::FromVariant; use crate::types::DeriveMacroSnapshot; +/// Snapshots the expansion of `derive_from_variant`. pub fn snapshot_derive_from_variant(body: TokenStream) -> syn::Result { let item: DeriveMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs index 6b7938f9c..99ba3f534 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs @@ -5,6 +5,7 @@ use syn::{ItemStruct, parse2}; use crate::keywords::HasField; use crate::types::DeriveMacroSnapshot; +/// Snapshots the expansion of `derive_has_field`. pub fn snapshot_derive_has_field(body: TokenStream) -> syn::Result { let item: DeriveMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs index 388a62908..ca912d68d 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs @@ -5,6 +5,7 @@ use syn::{Item, parse2}; use crate::keywords::HasFields; use crate::types::DeriveMacroSnapshot; +/// Snapshots the expansion of `derive_has_fields`. pub fn snapshot_derive_has_fields(body: TokenStream) -> syn::Result { let item: DeriveMacroSnapshot = parse2(body)?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs index 85259f88a..040dc26c1 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs @@ -5,6 +5,7 @@ use syn::parse::ParseStream; use syn::token::Paren; use syn::{braced, bracketed, parenthesized}; +/// Parses `#[keyword(...)]` or `#[keyword{...}]` and returns the inner tokens. pub fn parse_attribute_with_keyword(input: ParseStream) -> syn::Result { let outer_body; bracketed!(outer_body in input); diff --git a/crates/macros/cgp-macro-test-util-lib/src/functions/pretty_format.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/pretty_format.rs index 034c11d11..ce93ed449 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/functions/pretty_format.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/pretty_format.rs @@ -3,6 +3,7 @@ use prettyplease::unparse; use proc_macro2::TokenStream; use syn::parse2; +/// Formats a token stream as Rust source for the snapshot. pub fn pretty_format(body: TokenStream) -> syn::Result { let parsed = parse2(strip_macro_prelude(body))?; let formatted = unparse(&parsed); diff --git a/crates/macros/cgp-macro-test-util-lib/src/lib.rs b/crates/macros/cgp-macro-test-util-lib/src/lib.rs index 287ff3c7c..6520998ba 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/lib.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/lib.rs @@ -1,6 +1,11 @@ //! This crate implements CGP's snapshot-testing macros. +#![warn(missing_docs)] +/// The snapshot macros' entry points, one per construct. pub mod entrypoints; +/// The shared parsing and formatting helpers. pub mod functions; +/// The keyword markers the snapshot macros parse. pub mod keywords; +/// The snapshot input types. pub mod types; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs index 16e89776b..0e5b41ad1 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs @@ -8,10 +8,15 @@ use syn::token::Pound; use crate::functions::parse_attribute_with_keyword; use crate::types::MacroSnapshot; +/// The input of an attribute-macro snapshot: the attribute, the item, and the assertion. pub struct AttributeMacroSnapshot { + /// The attribute's inner tokens. pub attr: TokenStream, + /// The annotated item. pub body: Item, + /// The snapshot's test name and assertion. pub snapshot: MacroSnapshot, + /// The keyword marker. pub phantom: PhantomData, } diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/derive_snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/derive_snapshot.rs index 0d190b9bf..7988db7d7 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/derive_snapshot.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/derive_snapshot.rs @@ -10,9 +10,13 @@ use crate::functions::parse_attribute_with_keyword; use crate::keywords::Derive; use crate::types::MacroSnapshot; +/// The input of a derive-macro snapshot: the item and the assertion. pub struct DeriveMacroSnapshot { + /// The annotated item. pub body: Item, + /// The snapshot's test name and assertion. pub snapshot: MacroSnapshot, + /// The keyword marker. pub phantom: PhantomData, } diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/macro_snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/macro_snapshot.rs index 0981c916f..84198ef37 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/macro_snapshot.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/macro_snapshot.rs @@ -6,13 +6,18 @@ use syn::{Ident, LitStr, braced, parenthesized}; use crate::functions::pretty_format; +/// The test name, the identifier the snapshot is bound to, and the assertion. pub struct MacroSnapshot { + /// The generated test's name. pub test_name: Ident, + /// The identifier the snapshot string is bound to. pub arg_ident: Ident, + /// The assertion that checks the snapshot. pub expr: TokenStream, } impl MacroSnapshot { + /// Wraps the generated code and a test that pins its formatted form. pub fn wrap_output(&self, output: TokenStream) -> syn::Result { let Self { test_name, diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/statement_snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/statement_snapshot.rs index 7370eca0a..42033b301 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/statement_snapshot.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/statement_snapshot.rs @@ -9,9 +9,13 @@ use syn::token::Not; use crate::types::MacroSnapshot; +/// The input of a statement-macro snapshot: the body and the assertion. pub struct StatementMacroSnapshot { + /// The macro's body tokens. pub body: TokenStream, + /// The snapshot's test name and assertion. pub snapshot: MacroSnapshot, + /// The keyword marker. pub phantom: PhantomData, } diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 74ae91076..27e9cc901 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -1,9 +1,11 @@ //! This crate provides CGP's snapshot-testing macros, which emit the real generated code and pin it //! as an inline `insta` snapshot. +#![warn(missing_docs)] use cgp_macro_test_util_lib::entrypoints; use proc_macro::TokenStream; +/// Snapshots the expansion of `delegate_components`. #[proc_macro] pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { entrypoints::snapshot_delegate_components(body.into()) @@ -11,6 +13,7 @@ pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_component`. #[proc_macro] pub fn snapshot_cgp_component(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_component(body.into()) @@ -18,6 +21,7 @@ pub fn snapshot_cgp_component(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_impl`. #[proc_macro] pub fn snapshot_cgp_impl(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_impl(body.into()) @@ -25,6 +29,7 @@ pub fn snapshot_cgp_impl(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_provider`. #[proc_macro] pub fn snapshot_cgp_provider(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_provider(body.into()) @@ -32,6 +37,7 @@ pub fn snapshot_cgp_provider(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_new_provider`. #[proc_macro] pub fn snapshot_cgp_new_provider(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_new_provider(body.into()) @@ -39,6 +45,7 @@ pub fn snapshot_cgp_new_provider(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_fn`. #[proc_macro] pub fn snapshot_cgp_fn(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_fn(body.into()) @@ -46,6 +53,7 @@ pub fn snapshot_cgp_fn(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_auto_getter`. #[proc_macro] pub fn snapshot_cgp_auto_getter(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_auto_getter(body.into()) @@ -53,6 +61,7 @@ pub fn snapshot_cgp_auto_getter(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_getter`. #[proc_macro] pub fn snapshot_cgp_getter(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_getter(body.into()) @@ -60,6 +69,7 @@ pub fn snapshot_cgp_getter(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_namespace`. #[proc_macro] pub fn snapshot_cgp_namespace(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_namespace(body.into()) @@ -67,6 +77,7 @@ pub fn snapshot_cgp_namespace(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_type`. #[proc_macro] pub fn snapshot_cgp_type(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_type(body.into()) @@ -74,6 +85,7 @@ pub fn snapshot_cgp_type(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `check_components`. #[proc_macro] pub fn snapshot_check_components(body: TokenStream) -> TokenStream { entrypoints::snapshot_check_components(body.into()) @@ -81,6 +93,7 @@ pub fn snapshot_check_components(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `delegate_and_check_components`. #[proc_macro] pub fn snapshot_delegate_and_check_components(body: TokenStream) -> TokenStream { entrypoints::snapshot_delegate_and_check_components(body.into()) @@ -88,6 +101,7 @@ pub fn snapshot_delegate_and_check_components(body: TokenStream) -> TokenStream .into() } +/// Snapshots the expansion of `blanket_trait`. #[proc_macro] pub fn snapshot_blanket_trait(body: TokenStream) -> TokenStream { entrypoints::snapshot_blanket_trait(body.into()) @@ -95,6 +109,7 @@ pub fn snapshot_blanket_trait(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `derive_has_field`. #[proc_macro] pub fn snapshot_derive_has_field(body: TokenStream) -> TokenStream { entrypoints::snapshot_derive_has_field(body.into()) @@ -102,6 +117,7 @@ pub fn snapshot_derive_has_field(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `derive_has_fields`. #[proc_macro] pub fn snapshot_derive_has_fields(body: TokenStream) -> TokenStream { entrypoints::snapshot_derive_has_fields(body.into()) @@ -109,6 +125,7 @@ pub fn snapshot_derive_has_fields(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `derive_cgp_data`. #[proc_macro] pub fn snapshot_derive_cgp_data(body: TokenStream) -> TokenStream { entrypoints::snapshot_derive_cgp_data(body.into()) @@ -116,6 +133,7 @@ pub fn snapshot_derive_cgp_data(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `derive_build_field`. #[proc_macro] pub fn snapshot_derive_build_field(body: TokenStream) -> TokenStream { entrypoints::snapshot_derive_build_field(body.into()) @@ -123,6 +141,7 @@ pub fn snapshot_derive_build_field(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `derive_extract_field`. #[proc_macro] pub fn snapshot_derive_extract_field(body: TokenStream) -> TokenStream { entrypoints::snapshot_derive_extract_field(body.into()) @@ -130,6 +149,7 @@ pub fn snapshot_derive_extract_field(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `derive_from_variant`. #[proc_macro] pub fn snapshot_derive_from_variant(body: TokenStream) -> TokenStream { entrypoints::snapshot_derive_from_variant(body.into()) @@ -137,6 +157,7 @@ pub fn snapshot_derive_from_variant(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_computer`. #[proc_macro] pub fn snapshot_cgp_computer(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_computer(body.into()) @@ -144,6 +165,7 @@ pub fn snapshot_cgp_computer(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_producer`. #[proc_macro] pub fn snapshot_cgp_producer(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_producer(body.into()) @@ -151,6 +173,7 @@ pub fn snapshot_cgp_producer(body: TokenStream) -> TokenStream { .into() } +/// Snapshots the expansion of `cgp_auto_dispatch`. #[proc_macro] pub fn snapshot_cgp_auto_dispatch(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_auto_dispatch(body.into()) diff --git a/crates/macros/cgp-macro/src/lib.rs b/crates/macros/cgp-macro/src/lib.rs index 52e7e80b0..9fb333cde 100644 --- a/crates/macros/cgp-macro/src/lib.rs +++ b/crates/macros/cgp-macro/src/lib.rs @@ -3,6 +3,7 @@ //! context. //! //! See [`#[cgp_component]`](https://contextgeneric.dev/docs/reference/macros/cgp_component), [`#[cgp_impl]`](https://contextgeneric.dev/docs/reference/macros/cgp_impl), [`delegate_components!`](https://contextgeneric.dev/docs/reference/macros/delegate_components), and [`check_components!`](https://contextgeneric.dev/docs/reference/macros/check_components). +#![warn(missing_docs)] use proc_macro::TokenStream; @@ -204,6 +205,9 @@ pub fn cgp_impl(attr: TokenStream, item: TokenStream) -> TokenStream { .into() } +/// Turn a plain Rust function into a trait with a single blanket implementation, so it runs on any context that supplies the fields it needs. +/// +/// See [`cgp_fn`](https://contextgeneric.dev/docs/reference/macros/cgp_fn). #[proc_macro_attribute] pub fn cgp_fn(attr: TokenStream, item: TokenStream) -> TokenStream { cgp_macro_lib::cgp_fn(attr.into(), item.into()) @@ -535,6 +539,9 @@ pub fn delegate_components(body: TokenStream) -> TokenStream { .into() } +/// Define a reusable, inheritable wiring table that many contexts can join, so a configuration stays short as the component count grows. +/// +/// See [`cgp_namespace`](https://contextgeneric.dev/docs/reference/macros/cgp_namespace). #[proc_macro] pub fn cgp_namespace(body: TokenStream) -> TokenStream { cgp_macro_lib::cgp_namespace(body.into()) @@ -791,6 +798,9 @@ pub fn Product(body: TokenStream) -> TokenStream { .into() } +/// A type-level list and its value-level counterpart, used for the field lists of a record and for handler pipelines. +/// +/// See [`product`](https://contextgeneric.dev/docs/reference/macros/product). #[proc_macro] pub fn product(body: TokenStream) -> TokenStream { cgp_macro_lib::product(body.into()) @@ -898,6 +908,9 @@ pub fn Enum(body: TokenStream) -> TokenStream { .into() } +/// A type-level path, used by CGP namespaces and by component lookups that are redirected along one. +/// +/// See [`path`](https://contextgeneric.dev/docs/reference/macros/path). #[proc_macro] #[allow(non_snake_case)] pub fn Path(body: TokenStream) -> TokenStream { @@ -906,6 +919,9 @@ pub fn Path(body: TokenStream) -> TokenStream { .into() } +/// Generate shared and mutable accessors for every field of a struct, keyed by type-level tags, which is what lets an implicit argument find a field. +/// +/// See [`derive_has_field`](https://contextgeneric.dev/docs/reference/derives/derive_has_field). #[proc_macro_derive(HasField)] pub fn derive_fields(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_has_field(item.into()) @@ -913,6 +929,9 @@ pub fn derive_fields(item: TokenStream) -> TokenStream { .into() } +/// Generate a structural representation of a struct or enum and the conversions to and from it, exposing its whole field or variant list to generic code. +/// +/// See [`derive_has_fields`](https://contextgeneric.dev/docs/reference/derives/derive_has_fields). #[proc_macro_derive(HasFields)] pub fn derive_has_fields(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_has_fields(item.into()) @@ -920,6 +939,9 @@ pub fn derive_has_fields(item: TokenStream) -> TokenStream { .into() } +/// Generate a builder that tracks in its own type which fields of a struct have been supplied, so an incomplete record cannot be finalized. +/// +/// See [`derive_build_field`](https://contextgeneric.dev/docs/reference/derives/derive_build_field). #[proc_macro_derive(BuildField)] pub fn derive_builder(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_build_field(item.into()) @@ -927,6 +949,9 @@ pub fn derive_builder(item: TokenStream) -> TokenStream { .into() } +/// Generate an extractor that tracks in its own type which variants of an enum remain, so exhaustiveness is checked without a wildcard arm. +/// +/// See [`derive_extract_field`](https://contextgeneric.dev/docs/reference/derives/derive_extract_field). #[proc_macro_derive(ExtractField)] pub fn derive_extractor(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_extract_field(item.into()) @@ -934,6 +959,9 @@ pub fn derive_extractor(item: TokenStream) -> TokenStream { .into() } +/// Let generic code construct an enum variant selected by a type-level tag, without naming the variant or the enum. +/// +/// See [`derive_from_variant`](https://contextgeneric.dev/docs/reference/derives/derive_from_variant). #[proc_macro_derive(FromVariant)] pub fn derive_from_variant(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_from_variant(item.into()) @@ -941,6 +969,9 @@ pub fn derive_from_variant(item: TokenStream) -> TokenStream { .into() } +/// Generate a structural representation, constructors, and an extractor for an enum, as the variant half of the extensible-data derives. +/// +/// See [`derive_cgp_variant`](https://contextgeneric.dev/docs/reference/derives/derive_cgp_variant). #[proc_macro_derive(CgpVariant)] pub fn derive_cgp_variant(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_cgp_variant(item.into()) @@ -948,6 +979,9 @@ pub fn derive_cgp_variant(item: TokenStream) -> TokenStream { .into() } +/// Generate field access, a structural representation, and a builder for a struct, as the record half of the extensible-data derives. +/// +/// See [`derive_cgp_record`](https://contextgeneric.dev/docs/reference/derives/derive_cgp_record). #[proc_macro_derive(CgpRecord)] pub fn derive_cgp_record(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_cgp_record(item.into()) @@ -955,6 +989,9 @@ pub fn derive_cgp_record(item: TokenStream) -> TokenStream { .into() } +/// Generate structural access and the incremental building and extraction operations for a struct or enum, as the umbrella over the narrower derives. +/// +/// See [`derive_cgp_data`](https://contextgeneric.dev/docs/reference/derives/derive_cgp_data). #[proc_macro_derive(CgpData)] pub fn derive_cgp_data(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_cgp_data(item.into()) diff --git a/crates/main/cgp-base-extra/src/lib.rs b/crates/main/cgp-base-extra/src/lib.rs index 764137168..3632a8dd6 100644 --- a/crates/main/cgp-base-extra/src/lib.rs +++ b/crates/main/cgp-base-extra/src/lib.rs @@ -2,7 +2,9 @@ //! This crate re-exports CGP's base layer with the abstract-type layer added. //! //! See [`HasType`](https://contextgeneric.dev/docs/reference/components/has_type). +#![warn(missing_docs)] +/// The prelude, re-exported as `cgp_base_extra::macro_prelude`. pub mod macro_prelude; pub use cgp_base::{component, types}; diff --git a/crates/main/cgp-base/src/lib.rs b/crates/main/cgp-base/src/lib.rs index 064bc6897..67ccb6732 100644 --- a/crates/main/cgp-base/src/lib.rs +++ b/crates/main/cgp-base/src/lib.rs @@ -3,7 +3,9 @@ //! //! See [`#[cgp_component]`](https://contextgeneric.dev/docs/reference/macros/cgp_component), [`Symbol!`](https://contextgeneric.dev/docs/reference/macros/symbol), and [`Cons`](https://contextgeneric.dev/docs/reference/types/cons). #![no_std] +#![warn(missing_docs)] +/// The prelude, re-exported as `cgp_base::macro_prelude`. pub mod macro_prelude; pub use cgp_base_types::*; diff --git a/crates/main/cgp-core/src/lib.rs b/crates/main/cgp-core/src/lib.rs index 8fa7228b4..b0481d19b 100644 --- a/crates/main/cgp-core/src/lib.rs +++ b/crates/main/cgp-core/src/lib.rs @@ -4,7 +4,9 @@ //! async trait macro, and the error, field, and type components. //! //! See [`#[cgp_component]`](https://contextgeneric.dev/docs/reference/macros/cgp_component), [`HasField`](https://contextgeneric.dev/docs/reference/traits/field-access/has_field), and [`HasErrorType`](https://contextgeneric.dev/docs/reference/components/has_error_type). +#![warn(missing_docs)] +/// The prelude, re-exported as `cgp_core::prelude` and `cgp_core::macro_prelude`. pub mod prelude; pub use prelude as macro_prelude; diff --git a/crates/main/cgp-extra/src/lib.rs b/crates/main/cgp-extra/src/lib.rs index 3e612eb9d..43e44bd22 100644 --- a/crates/main/cgp-extra/src/lib.rs +++ b/crates/main/cgp-extra/src/lib.rs @@ -4,7 +4,9 @@ //! turns on the providers that need an allocator. //! //! See [`CanHandle`](https://contextgeneric.dev/docs/reference/components/handler/handler), [`PipeHandlers`](https://contextgeneric.dev/docs/reference/providers/handler/pipe_handlers), and [`RaiseFrom`](https://contextgeneric.dev/docs/reference/providers/error/raise_from). +#![warn(missing_docs)] +/// The prelude, re-exported as `cgp_extra::prelude`. pub mod prelude; pub use cgp_dispatch as dispatch; diff --git a/crates/main/cgp/src/lib.rs b/crates/main/cgp/src/lib.rs index 08ca34276..bf98e6a31 100644 --- a/crates/main/cgp/src/lib.rs +++ b/crates/main/cgp/src/lib.rs @@ -1,9 +1,11 @@ #![no_std] #![doc = include_str!("../README.md")] +#![warn(missing_docs)] #[doc(inline)] pub use {cgp_core as core, cgp_extra as extra}; +/// The prelude, re-exported as `cgp::prelude` and `cgp::macro_prelude`. pub mod prelude; pub use prelude as macro_prelude; diff --git a/crates/standalone/error/cgp-error-anyhow/src/lib.rs b/crates/standalone/error/cgp-error-anyhow/src/lib.rs index 1fa6362c2..5152fc574 100644 --- a/crates/standalone/error/cgp-error-anyhow/src/lib.rs +++ b/crates/standalone/error/cgp-error-anyhow/src/lib.rs @@ -1,5 +1,6 @@ #![doc = include_str!("../README.md")] #![no_std] +#![warn(missing_docs)] extern crate alloc; diff --git a/crates/standalone/error/cgp-error-eyre/src/lib.rs b/crates/standalone/error/cgp-error-eyre/src/lib.rs index 1116786fe..725794cbd 100644 --- a/crates/standalone/error/cgp-error-eyre/src/lib.rs +++ b/crates/standalone/error/cgp-error-eyre/src/lib.rs @@ -1,4 +1,5 @@ #![doc = include_str!("../README.md")] +#![warn(missing_docs)] // eyre needs `std`, so unlike the other backends this crate is not `no_std`. extern crate alloc; diff --git a/crates/standalone/error/cgp-error-std/src/lib.rs b/crates/standalone/error/cgp-error-std/src/lib.rs index 31f96ebc3..cbd6d0515 100644 --- a/crates/standalone/error/cgp-error-std/src/lib.rs +++ b/crates/standalone/error/cgp-error-std/src/lib.rs @@ -1,5 +1,6 @@ #![doc = include_str!("../README.md")] #![no_std] +#![warn(missing_docs)] extern crate alloc; diff --git a/crates/standalone/error/cgp-error-std/src/types/string.rs b/crates/standalone/error/cgp-error-std/src/types/string.rs index 79ffd47af..09d2aef93 100644 --- a/crates/standalone/error/cgp-error-std/src/types/string.rs +++ b/crates/standalone/error/cgp-error-std/src/types/string.rs @@ -5,6 +5,7 @@ use core::fmt::{Debug, Display}; /// A standard error that carries only a message, produced when a provider formats a value that is /// not itself a standard error. pub struct StringError { + /// The error's message. pub message: String, } diff --git a/crates/standalone/error/cgp-error-std/src/types/wrap.rs b/crates/standalone/error/cgp-error-std/src/types/wrap.rs index ba85437c9..9eb3a4a80 100644 --- a/crates/standalone/error/cgp-error-std/src/types/wrap.rs +++ b/crates/standalone/error/cgp-error-std/src/types/wrap.rs @@ -10,7 +10,9 @@ use crate::Error; /// `{}` prints the detail alone, so a reporter that walks `source()` prints each message once. /// `{:#}` and `{:?}` print the whole chain, joined by `": "`. pub struct WrapError { + /// The detail added to the wrapped error. pub detail: String, + /// The error the detail wraps. pub source: Error, }