Struct Leaker

Source
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

Source

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();
Source

pub fn from_enum(input: &ItemEnum) -> Result<Self, NotInternableError>

Initialize with ItemEnum

Source

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)));
Source

pub fn with_generics_and_implementor( generics: Generics, implementor_type_fn: Box<dyn Fn(PathArguments) -> Type>, ) -> Self

Initialize empty Leaker with given generics.

Types, consts, lifetimes defined in the Generics is treated as “no needs to be interned” although they looks like relative path names.

Source

pub fn intern( &mut self, generics: Generics, ty: &Type, ) -> Result<&mut Self, NotInternableError>

Intern the given type as a root node.

Source

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.

Source

pub fn finish( self, repeater_path_fn: impl FnMut(usize) -> Path, ) -> (Vec<ItemImpl>, Referrer)

Finish building the Leaker and convert it into Referrer.

Source

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:

graph TD 1["★MyType1 (Node 1)"] 2["★(MyType2, MyType3#lt;MyType1#gt;, MyType4, MyType5) (Node 2)"] -->3["MyType2 (Node 3)"] 2 -->4["MyType3#lt;MyType1#gt; (Node 4)"] 2 -->0["★MyType4 (Node 0)"] 2 -->5["MyType5 (Node 5)"] 6["★&a (T1, T2) (Node 6)"] -->7["(T1, T2) (Node 7)"] 7 -->8["T1 (Node 8)"] 7 -->9["T2 (Node 9)"] classDef redNode stroke:#ff0000; class 0,1,3,4,5 redNode;

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:

graph TD 0["MyType4 (Node 0)"] 1["MyType1 (Node 1)"] 2["(MyType2, MyType3 #lt; MyType1 #gt;, MyType4, MyType5) (Node 2)"] classDef redNode stroke:#ff0000; class 0,1,2 redNode;

Auto Trait Implementations§

§

impl Freeze for Leaker

§

impl !RefUnwindSafe for Leaker

§

impl !Send for Leaker

§

impl !Sync for Leaker

§

impl Unpin for Leaker

§

impl !UnwindSafe for Leaker

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.