Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

func type workarounds #399

Closed
16 tasks done
lastmjs opened this issue Jun 13, 2022 · 1 comment · Fixed by #442
Closed
16 tasks done

func type workarounds #399

lastmjs opened this issue Jun 13, 2022 · 1 comment · Fixed by #442
Assignees
Milestone

Comments

@lastmjs
Copy link
Member

lastmjs commented Jun 13, 2022

  • All func example tests should pass
  • All func example TODOs addressed
  • All ledger and http functionality should work (we should have tests for ledger)
  • Test the http motoko example, make sure the callback works (streaming)
  • We should be able to pass functions in parameters and return them from functions
  • Any issue we ran into should be overcome
  • Generate all func Rust types as unit structs with the correct impls
  • Figure out how to remove func types from the automatically generated Rust code
  • Suggested steps
    • Replace all instances of candid::Func or the unit struct with candid::Func with a new struct with some custom impls
    • Or maybe I can create a new struct that the other types can be into() into...instead of having to replace all of the structs
  • Get Oneway to work better (no type)
  • Make func tests a bit more elaborate (especially test oneway func and maybe a cross-canister call?)
  • Related: TypeScript -> Candid compiler implement func #86
  • Vecs as func params are breaking
  • Open up issue or forum post to find out why dfinity agent is interpreting some func types strangly
@lastmjs lastmjs self-assigned this Jun 13, 2022
@dansteren dansteren added this to the June milestone Jun 20, 2022
@lastmjs
Copy link
Member Author

lastmjs commented Jun 22, 2022

This seems to wotk, gettinh close:

        // TODO start custom Func implementation

        // type BasicFunc = candid::Func;

        /// A marker type to match unconstrained callback arguments
        #[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
        pub struct ArgToken;

        impl CandidType for ArgToken {
            fn _ty() -> candid::types::Type {
                candid::types::Type::Empty
            }

            fn idl_serialize<S: candid::types::Serializer>(&self, _serializer: S) -> Result<(), S::Error> {
                // We cannot implement serialize, since our type must be `Empty` in order to accept anything.
                // Attempting to serialize this type is always an error and should be regarded as a compile time error.
                unimplemented!("Token is not serializable")
            }
        }

        #[derive(Debug, Clone)]
        struct BasicFunc<ArgToken = self::ArgToken>(
            pub candid::Func,
            pub std::marker::PhantomData<ArgToken>,
        );

        impl AzleIntoJsValue for BasicFunc {
            fn azle_into_js_value(self, context: &mut boa_engine::Context) -> boa_engine::JsValue {
                self.0.azle_into_js_value(context)
            }
        }

        impl AzleTryFromJsValue<BasicFunc<ArgToken>> for boa_engine::JsValue {
            fn azle_try_from_js_value(self, context: &mut boa_engine::Context) -> Result<BasicFunc<ArgToken>, AzleTryFromJsValueError> {
                let candid_func: candid::Func = self.azle_try_from_js_value(context).unwrap();
                Ok(candid_func.into())
            }
        }

        impl<ArgToken: CandidType> CandidType for BasicFunc<ArgToken> {
            fn _ty() -> candid::types::Type {
                // TODO this is the part that needs to be generated from the TypeScript type for type
                // TODO basically go grab all of the Funcs, grab the query/update, and grab the args and return type
                // TODO should not be too bad actually
                candid::types::Type::Func(candid::types::Function {
                    modes: vec![candid::parser::types::FuncMode::Query],
                    args: vec![candid::types::Type::Text],
                    rets: vec![candid::types::Type::Text]
                })
            }

            fn idl_serialize<S: candid::types::Serializer>(&self, serializer: S) -> Result<(), S::Error> {
                self.0.idl_serialize(serializer)
            }
        }

        impl<'de, ArgToken> Deserialize<'de> for BasicFunc<ArgToken> {
            fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
                candid::Func::deserialize(deserializer).map(Self::from)
            }
        }
        
        impl<ArgToken> From<candid::Func> for BasicFunc<ArgToken> {
            fn from(f: candid::Func) -> Self {
                Self(f, std::marker::PhantomData)
            }
        }
        
        impl<ArgToken> From<BasicFunc<ArgToken>> for candid::Func {
            fn from(c: BasicFunc<ArgToken>) -> Self {
                c.0
            }
        }
        
        impl<ArgToken> std::ops::Deref for BasicFunc<ArgToken> {
            type Target = candid::Func;
            fn deref(&self) -> &candid::Func {
                &self.0
            }
        }
        
        impl<ArgToken> std::ops::DerefMut for BasicFunc<ArgToken> {
            fn deref_mut(&mut self) -> &mut candid::Func {
                &mut self.0
            }
        }

        // TODO end custom Func implementation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants