🏡 index : ~doyle/tinfoil.git

author Jordan Doyle <jordan@doyle.la> 2021-06-20 3:22:19.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-06-20 3:22:19.0 +01:00:00
commit
389de655d489f6ccc14ad2df4cca0ebd2203f140 [patch]
tree
9fcbc8cff04f20786df900d3bd50a56906ae910d
parent
783fdef6f23114c451b8da90a11b4c2e81884eb1
download
master.tar.gz

Loosen clause on instn



Diff

 tinfoil/Cargo.toml                   |  4 +++-
 tinfoil-macros/src/implementation.rs | 22 +++++++++++++++++-----
 tinfoil-tests/src/lib.rs             |  2 +-
 tinfoil/src/lib.rs                   |  6 +++---
 4 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/tinfoil/Cargo.toml b/tinfoil/Cargo.toml
index 382c4af..26a9339 100644
--- a/tinfoil/Cargo.toml
+++ a/tinfoil/Cargo.toml
@@ -1,11 +1,13 @@
[package]
name = "tinfoil"
version = "0.0.1"
authors = ["Jordan Doyle <jordan@doyle.la>"]
edition = "2018"
description = ""

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
daggy = "0.7"
petgraph = "0.5"
petgraph = "0.5"
tinfoil-macros = { path = "../tinfoil-macros" }
diff --git a/tinfoil-macros/src/implementation.rs b/tinfoil-macros/src/implementation.rs
index 3128509..42c578a 100644
--- a/tinfoil-macros/src/implementation.rs
+++ a/tinfoil-macros/src/implementation.rs
@@ -30,26 +30,31 @@
    let input: DeriveInput = syn::parse(input).map_err(|e| e.to_compile_error())?;

    let name = &input.ident;
    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();

    let s = match input.data {
        Data::Struct(v) => v,
        _ => panic!("not a struct"),
    };
    let typ = s.fields.iter().map(|v| &v.ty);
    let types = s
        .fields
        .iter()
        .map(|v| replace_lifetimes_with_static(&v.ty));
    let fields = s.fields.iter().map(|v| &v.ident);

    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();

    // TODO: support generics from #ty_generics
    let expanded = quote! {
        #[allow(missing_docs, single_use_lifetimes)]
        impl #impl_generics Dependency<'a, InjectionContext<'a>> for #name #ty_generics #where_clause {
        impl #impl_generics tinfoil::Dependency for #name #ty_generics #where_clause {
            const DEPENDENCIES: &'static [std::any::TypeId] = &[
                #(std::any::TypeId::of::<#types>()),*
            ];
        }

            fn instn(context: &'a InjectionContext<'a>) -> Self {
        impl #impl_generics #name #ty_generics #where_clause {
            pub fn instn<C: 'a + #(tinfoil::Provider<'a, #typ>)+*>(context: &'a C) -> Self {
                Self {
                    #(#fields: context.get()),*
                }
@@ -138,20 +143,21 @@
    let expanded = quote! {
        impl #impl_generics #name #ty_generics #where_clause {
            pub fn new(#(#parameters: #parameter_types),*) -> Pin<Box<Self>> {
                let mut context = Box::pin(InjectionContext {
                let mut context = Box::pin(Self {
                    #(#parameters,)*
                    #(#defaults: Default::default(),)*
                    #(#instantiate_from_ctx: MaybeUninit::uninit(),)*
                    _pin: PhantomPinned,
                });

                /// TODO: this needs to be compile time checked

                let mut dag: tinfoil::internals::Dag<i32, i32, usize> = tinfoil::internals::Dag::new();
                let initial = dag.add_node(0);
                let mut nodes = std::collections::HashMap::new();
                // TODO: fix generics & run through `replace_lifetimes_with_static`
                #(nodes.insert(std::any::TypeId::of::<&'static #instantiate_from_ctx_types<'static>>(), {
                    let node = dag.add_node(0);
                    dag.add_edge(initial, node, 0);
                    dag.add_edge(initial, node, 0).unwrap();
                    node
                });)*

@@ -180,13 +186,13 @@
                    if false {}
                    #(else if ty == std::any::TypeId::of::<&'static #instantiate_from_ctx_types<'static>>() {
                        // this is safe because we know MyCoolValue is initialised and will be for the lifetime of
                        // InjectionContext
                        // Self
                        let value = MaybeUninit::new(#instantiate_from_ctx_types::instn(context.as_ref().get_ref()));

                        // this is safe because we don't move any values
                        unsafe {
                            // let mut_ref: Pin<&mut InjectionContext> = Pin::as_mut(&mut context);
                            let mut_ref: Pin<&mut InjectionContext> = std::mem::transmute(context.as_ref());
                            // let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut context);
                            let mut_ref: Pin<&mut #name> = std::mem::transmute(context.as_ref());
                            Pin::get_unchecked_mut(mut_ref).#instantiate_from_ctx = value;
                        }
                    })*
diff --git a/tinfoil-tests/src/lib.rs b/tinfoil-tests/src/lib.rs
index 52fdb86..9757992 100644
--- a/tinfoil-tests/src/lib.rs
+++ a/tinfoil-tests/src/lib.rs
@@ -1,10 +1,9 @@
#![feature(const_type_id)]
#![cfg(test)]

use std::marker::PhantomPinned;
use std::mem::MaybeUninit;
use std::pin::Pin;
use std::ptr::NonNull;
use tinfoil::{Dependency, Provider};
use tinfoil_macros::{Tinfoil, TinfoilContext};

@@ -26,6 +25,7 @@
#[derive(Tinfoil)]
pub struct OtherDependency<'a> {
    pub cool_dep: &'a CoolDependency<'a>,
    pub cool_value: &'a MyCoolValue,
}

#[derive(TinfoilContext)]
diff --git a/tinfoil/src/lib.rs b/tinfoil/src/lib.rs
index dea8e3d..46ee2d2 100644
--- a/tinfoil/src/lib.rs
+++ a/tinfoil/src/lib.rs
@@ -1,13 +1,13 @@
#![feature(const_type_id)]

pub mod internals;

pub use tinfoil_macros::{Tinfoil, TinfoilContext};

use std::any::TypeId;

pub trait Dependency<'a, C> {
pub trait Dependency {
    const DEPENDENCIES: &'static [TypeId];

    fn instn(context: &'a C) -> Self;
}

///////////////////