fn create_common_marshall(ecx: &mut ExtCtxt,
                          original_name: Ident,
                          method_sig: &ast::MethodSig) -> ImplItem {
    let mut marshall_sig = method_sig.clone();

    // Get a path to the `Marshall` trait.
    let marshall_trait_path = Path {
        segments: vec![
            PathSegment::from_ident(Ident::from_str("plugger_core"), DUMMY_SP),
            PathSegment::from_ident(Ident::from_str("Marshall"), DUMMY_SP),
        ],
        span: DUMMY_SP,
    };
    let marshall_trait_ref = PolyTraitRef::new(Vec::new(), marshall_trait_path, DUMMY_SP);

    // Add a type parameter for the module.
    // TODO: consider what happens when there is already a type parameter with this
    // name.
    marshall_sig.generics.ty_params.insert(0, TyParam {
        attrs: ThinVec::new(),
        ident: Ident::from_str("M"),
        id: DUMMY_NODE_ID,
        bounds: vec![TyParamBound::TraitTyParamBound(marshall_trait_ref, TraitBoundModifier::None)],
        default: None,
        span: DUMMY_SP,
    });

    let value_ty_path = ecx.path(DUMMY_SP, vec![
        Ident::from_str("M"), Ident::from_str("Value"),
    ]);
    let value_ty = ecx.ty_path(value_ty_path);

    marshall_sig.decl = util::replace_signature_types(marshall_sig.decl.clone(),
                                                      value_ty);

    // Create expressions to marshall given arguments to the correct arguments.
    let marshalled_args: Vec<_> = method_sig.decl.inputs.iter().map(|arg| {
        if arg.is_self() {
            ecx.expr_self(DUMMY_SP) // leave the self argument untouched
        } else { // map the argument to the correct type
            let arg_name = match arg.pat.node {
                PatKind::Ident(_, ref ident, _) => ident.node,
                _ => unimplemented!(),
            };

            match util::ty_kind(&arg.ty) {
                // A primitive type.
                util::TypeKind::Basic { name } => {
                    let marshall_fn = Ident::from_str(&format!("to_{}", name).to_lowercase());

                    P(quote_expr!(ecx, M::$marshall_fn($arg_name)).unwrap())
                },
                util::TypeKind::Custom { .. } => {
                    P(quote_expr!(ecx, &M::reference_from_value($arg_name)).unwrap())
                }
            }
        }
    }).collect();

    let original_fn_expr = quote_expr!(ecx, Self::$original_name);

    let call_expr = P(Expr {
        id: DUMMY_NODE_ID,
        span: DUMMY_SP,
        attrs: ThinVec::new(),
        node: ExprKind::Call(original_fn_expr, marshalled_args),
    });

    // Marshall the return value if present.
    let result_expr = match method_sig.decl.output {
        ast::FunctionRetTy::Default(..) => call_expr,
        ast::FunctionRetTy::Ty(ref ty) => {
            match util::ty_kind(&ty) {
                // A primitive type.
                util::TypeKind::Basic { name } => {
                    let marshall_fn = Ident::from_str(&format!("from_{}", name).to_lowercase());
                    quote_expr!(ecx, M::$marshall_fn($call_expr))
                },
                util::TypeKind::Custom { .. } => {
                    // quote_expr!(ecx, M::reference_to_value($call_expr))
                    unimplemented!();
                }
            }

        },
    };

    // Add statement to call original function.
    let result_stmt = Stmt {
        id: DUMMY_NODE_ID,
        span: DUMMY_SP,
        node: StmtKind::Expr(result_expr),
    };

    let block = Block {
        id: DUMMY_NODE_ID,
        span: DUMMY_SP,
        rules: BlockCheckMode::Default,
        stmts: vec![result_stmt],
    };

    ImplItem {
        id: DUMMY_NODE_ID,
        span: DUMMY_SP,
        ident: config::common_marshall_name(original_name),
        node: ImplItemKind::Method(marshall_sig, P(block)),
        vis: ast::Visibility::Public,
        defaultness: ast::Defaultness::Final,
        attrs: Vec::new(),
        tokens: None,
    }
}
/// Creates a common `<original_name>_marshall` method.
///
/// This can be used to marshall types from any language that has an implementation
/// of the `Marshall` trait.
Creates a common `_marshall` method.
This can be used to marshall types from any language that has an implementation
of the `Marshall` trait.
Creates a common ` _marshall ` method . This can be used to marshall types from any language that has an implementation of the ` Marshall ` trait .
fn create_common_marshall(ecx: &mut ExtCtxt,
                          original_name: Ident,
                          method_sig: &ast::MethodSig) -> ImplItem {
    let mut marshall_sig = method_sig.clone();
    // Get a path to the `Marshall` trait.
    let marshall_trait_path = Path {
        segments: vec![
            PathSegment::from_ident(Ident::from_str("plugger_core"), DUMMY_SP),
            PathSegment::from_ident(Ident::from_str("Marshall"), DUMMY_SP),
        ],
        span: DUMMY_SP,
    };
    let marshall_trait_ref = PolyTraitRef::new(Vec::new(), marshall_trait_path, DUMMY_SP);
    // Add a type parameter for the module.
    // TODO: consider what happens when there is already a type parameter with this
    // name.
    marshall_sig.generics.ty_params.insert(0, TyParam {
        attrs: ThinVec::new(),
        ident: Ident::from_str("M"),
        id: DUMMY_NODE_ID,
        bounds: vec![TyParamBound::TraitTyParamBound(marshall_trait_ref, TraitBoundModifier::None)],
        default: None,
        span: DUMMY_SP,
    });
    let value_ty_path = ecx.path(DUMMY_SP, vec![
        Ident::from_str("M"), Ident::from_str("Value"),
    ]);
    let value_ty = ecx.ty_path(value_ty_path);
    marshall_sig.decl = util::replace_signature_types(marshall_sig.decl.clone(),
                                                      value_ty);
    // Create expressions to marshall given arguments to the correct arguments.
    let marshalled_args: Vec<_> = method_sig.decl.inputs.iter().map(|arg| {
        if arg.is_self() {
            ecx.expr_self(DUMMY_SP) // leave the self argument untouched
        } else { // map the argument to the correct type
            let arg_name = match arg.pat.node {
                PatKind::Ident(_, ref ident, _) => ident.node,
                _ => unimplemented!(),
            };
            match util::ty_kind(&arg.ty) {
                // A primitive type.
                util::TypeKind::Basic { name } => {
                    let marshall_fn = Ident::from_str(&format!("to_{}", name).to_lowercase());
                    P(quote_expr!(ecx, M::$marshall_fn($arg_name)).unwrap())
                },
                util::TypeKind::Custom { .. } => {
                    P(quote_expr!(ecx, &M::reference_from_value($arg_name)).unwrap())
                }
            }
        }
    }).collect();
    let original_fn_expr = quote_expr!(ecx, Self::$original_name);
    let call_expr = P(Expr {
        id: DUMMY_NODE_ID,
        span: DUMMY_SP,
        attrs: ThinVec::new(),
        node: ExprKind::Call(original_fn_expr, marshalled_args),
    });
    // Marshall the return value if present.
    let result_expr = match method_sig.decl.output {
        ast::FunctionRetTy::Default(..) => call_expr,
        ast::FunctionRetTy::Ty(ref ty) => {
            match util::ty_kind(&ty) {
                // A primitive type.
                util::TypeKind::Basic { name } => {
                    let marshall_fn = Ident::from_str(&format!("from_{}", name).to_lowercase());
                    quote_expr!(ecx, M::$marshall_fn($call_expr))
                },
                util::TypeKind::Custom { .. } => {
                    // quote_expr!(ecx, M::reference_to_value($call_expr))
                    unimplemented!();
                }
            }
        },
    };
    // Add statement to call original function.
    let result_stmt = Stmt {
        id: DUMMY_NODE_ID,
        span: DUMMY_SP,
        node: StmtKind::Expr(result_expr),
    };
    let block = Block {
        id: DUMMY_NODE_ID,
        span: DUMMY_SP,
        rules: BlockCheckMode::Default,
        stmts: vec![result_stmt],
    };
    ImplItem {
        id: DUMMY_NODE_ID,
        span: DUMMY_SP,
        ident: config::common_marshall_name(original_name),
        node: ImplItemKind::Method(marshall_sig, P(block)),
        vis: ast::Visibility::Public,
        defaultness: ast::Defaultness::Final,
        attrs: Vec::new(),
        tokens: None,
    }
}
fn create_common_marshall ( ecx : & mut ExtCtxt , original_name : Ident , method_sig : & ast :: MethodSig ) -> ImplItem { let mut marshall_sig = method_sig . clone ( ) ; // Get a path to the `Marshall` trait. let marshall_trait_path = Path { segments : vec ! [ PathSegment from_ident ( Ident from_str ( " " ) DUMMY_SP ) PathSegment from_ident ( Ident from_str ( " " ) DUMMY_SP ) ] , span : DUMMY_SP , } ; let marshall_trait_ref = PolyTraitRef :: new ( Vec :: new ( ) , marshall_trait_path , DUMMY_SP ) ; // Add a type parameter for the module. // TODO: consider what happens when there is already a type parameter with this // name. marshall_sig . generics . ty_params . insert ( 0 , TyParam { attrs : ThinVec :: new ( ) , ident : Ident :: from_str ( " " ) , id : DUMMY_NODE_ID , bounds : vec ! [ TyParamBound TraitTyParamBound ( marshall_trait_ref TraitBoundModifier None ) ] , default : None , span : DUMMY_SP , } ) ; let value_ty_path = ecx . path ( DUMMY_SP , vec ! [ Ident from_str ( " " ) Ident from_str ( " " ) ] ) ; let value_ty = ecx . ty_path ( value_ty_path ) ; marshall_sig . decl = util :: replace_signature_types ( marshall_sig . decl . clone ( ) , value_ty ) ; // Create expressions to marshall given arguments to the correct arguments. let marshalled_args : Vec < _ > = method_sig . decl . inputs . iter ( ) . map ( | arg | { if arg . is_self ( ) { ecx . expr_self ( DUMMY_SP ) // leave the self argument untouched } else { // map the argument to the correct type let arg_name = match arg . pat . node { PatKind :: Ident ( _ , ref ident , _ ) => ident . node , _ => unimplemented ! ( ) , } ; match util :: ty_kind ( & arg . ty ) { // A primitive type. util :: TypeKind :: Basic { name } => { let marshall_fn = Ident :: from_str ( & format ! ( " " name ) . to_lowercase ( ) ) ; P ( quote_expr ! ( ecx M $ marshall_fn ( $ arg_name ) ) . unwrap ( ) ) } , util :: TypeKind :: Custom { .. } => { P ( quote_expr ! ( ecx M reference_from_value ( $ arg_name ) ) . unwrap ( ) ) } } } } ) . collect ( ) ; let original_fn_expr = quote_expr ! ( ecx Self $ original_name ) ; let call_expr = P ( Expr { id : DUMMY_NODE_ID , span : DUMMY_SP , attrs : ThinVec :: new ( ) , node : ExprKind :: Call ( original_fn_expr , marshalled_args ) , } ) ; // Marshall the return value if present. let result_expr = match method_sig . decl . output { ast :: FunctionRetTy :: Default ( .. ) => call_expr , ast :: FunctionRetTy :: Ty ( ref ty ) => { match util :: ty_kind ( & ty ) { // A primitive type. util :: TypeKind :: Basic { name } => { let marshall_fn = Ident :: from_str ( & format ! ( " " name ) . to_lowercase ( ) ) ; quote_expr ! ( ecx M $ marshall_fn ( $ call_expr ) ) } , util :: TypeKind :: Custom { .. } => { // quote_expr!(ecx, M::reference_to_value($call_expr)) unimplemented ! ( ) ; } } } , } ; // Add statement to call original function. let result_stmt = Stmt { id : DUMMY_NODE_ID , span : DUMMY_SP , node : StmtKind :: Expr ( result_expr ) , } ; let block = Block { id : DUMMY_NODE_ID , span : DUMMY_SP , rules : BlockCheckMode :: Default , stmts : vec ! [ result_stmt ] , } ; ImplItem { id : DUMMY_NODE_ID , span : DUMMY_SP , ident : config :: common_marshall_name ( original_name ) , node : ImplItemKind :: Method ( marshall_sig , P ( block ) ) , vis : ast :: Visibility :: Public , defaultness : ast :: Defaultness :: Final , attrs : Vec :: new ( ) , tokens : None , } }
Creates a common `<original_name>_marshall` method.
Creates a common ` <original_name > _marshall ` method .
ecx
&mut ExtCtxt
original_name
Ident
method_sig
&ast::MethodSig
ecx
&mut ExtCtxt
original_name
Ident
method_sig
&ast::MethodSig