pub struct Leaker {
pub implementor_type_fn: Box<dyn Fn(PathArguments) -> Type>,
/* private fields */
}Expand description
The entry point of this crate.
Fields§
§implementor_type_fn: Box<dyn Fn(PathArguments) -> Type>Marker path. It defaults to the type name when the input is enum or struct. When the input is a trait, the marker path should refers a type called marker type.
Referred by Leaker::finish().
Implementations§
Source§impl Leaker
impl Leaker
Sourcepub fn from_struct(input: &ItemStruct) -> Result<Self, NotInternableError>
pub fn from_struct(input: &ItemStruct) -> Result<Self, NotInternableError>
Initialize with ItemStruct
let test_struct: ItemStruct = parse_quote!(
pub struct MyStruct<'a, T1, T2: ::path::to::MyType1<MyType4>> {
field1: MyType1,
field2: (MyType2, MyType3<MyType1>, MyType4, MyType5),
field3: &'a (T1, T2),
}
);
let leaker = Leaker::from_struct(&test_struct).unwrap();Sourcepub fn from_enum(input: &ItemEnum) -> Result<Self, NotInternableError>
pub fn from_enum(input: &ItemEnum) -> Result<Self, NotInternableError>
Initialize with ItemEnum
Sourcepub fn from_trait(
input: &ItemTrait,
implementor_type_fn: Box<dyn Fn(PathArguments) -> Type>,
) -> Result<Self, NotInternableError>
pub fn from_trait( input: &ItemTrait, implementor_type_fn: Box<dyn Fn(PathArguments) -> Type>, ) -> Result<Self, NotInternableError>
Build an Leaker with given trait.
Unlike enum nor struct, it requires alternative path, an absolute path of a struct
which is declared the same crate with the leaker trait and also visible from
Referrers’ context. That struct is used as an impl target of Repeater
instead of the Leaker’s path.
let s: ItemTrait = parse_quote!{
pub trait MyTrait<T, U> {
fn func(self, t: T) -> U;
}
};
let alternate: ItemStruct = parse_quote!{
pub struct MyAlternate;
};
let _ = Leaker::from_trait(&s, Box::new(|_| parse_quote!(::path::to::Implementor)));Sourcepub fn with_generics_and_implementor(
generics: Generics,
implementor_type_fn: Box<dyn Fn(PathArguments) -> Type>,
) -> Self
pub fn with_generics_and_implementor( generics: Generics, implementor_type_fn: Box<dyn Fn(PathArguments) -> Type>, ) -> Self
Sourcepub fn intern(
&mut self,
generics: Generics,
ty: &Type,
) -> Result<&mut Self, NotInternableError>
pub fn intern( &mut self, generics: Generics, ty: &Type, ) -> Result<&mut Self, NotInternableError>
Intern the given type as a root node.
Sourcepub fn check(
&self,
generics: &Generics,
ty: &Type,
) -> Result<CheckResult, (Span, Span)>
pub fn check( &self, generics: &Generics, ty: &Type, ) -> Result<CheckResult, (Span, Span)>
Check that the internableness of give ty. It returns Err in contradiction (the type
must and must not be interned).
See CheckResult.
Sourcepub fn finish(
self,
repeater_path_fn: impl FnMut(usize) -> Path,
) -> (Vec<ItemImpl>, Referrer)
pub fn finish( self, repeater_path_fn: impl FnMut(usize) -> Path, ) -> (Vec<ItemImpl>, Referrer)
Sourcepub fn reduce_roots(&mut self)
pub fn reduce_roots(&mut self)
Reduce nodes to decrease cost of {Leaker}’s implementation.
§Algorithm
To consult the algorithm, see the following Leaker’s input:
pub struct MyStruct<'a, T1, T2: ::path::to::MyType1<MyType4>> {
field1: MyType1,
field2: (MyType2, MyType3<MyType1>, MyType4, MyType5),
field3: &'a (T1, T2),
}Leaker, when initialized with Leaker::from_struct(), analyze the AST and
construct a DAG which represents all (internable) types and the dependency relations like
this:
The red node is flagged as CheckResult::MustIntern by Leaker::check() (which means
the type literature depends on the type context, so it must be interned).
This algorithm reduce the nodes, remaining that all root type (annotated with ★) can be expressed with existing red nodes.
Here, there are some choice in its freedom:
- Intern all red nodes and ignore others (because other nodes are not needed to be intern, or constructable with red nodes)
- Not directly intern red nodes; intern common ancessors instead if it is affordable.
So finally, it results like: