odoo_api_macros/lib.rs
1//! Helper macros for the `odoo_api` crate
2//!
3//! See the [`odoo_api`](https://crates.io/crates/odoo-api) crate.
4
5use proc_macro::TokenStream;
6
7mod common;
8mod error;
9mod odoo_api;
10mod odoo_orm;
11mod odoo_web;
12mod serialize_tuple;
13
14use common::parse_result;
15use error::{Error, Result};
16use syn::parse_macro_input;
17
18/// Implement traits for an "API" method struct
19///
20/// The input should be a struct with named field. Zero-sized structs and generics
21/// are supported.
22///
23/// Arguments:
24/// - Service: The Odoo "service" for this method
25/// - Method: The method name
26/// - Auth: Whether authentication is required, optional, or ignored
27///
28/// For example, consider the following:
29/// ```ignore
30/// // service: "object"
31/// // method: "execute"
32/// // auth: "yes"
33/// #[derive(Debug, Serialize)]
34/// #[odoo_api("object", "execute", "yes")]
35/// struct Execute {
36/// database: String,
37/// uid: OdooId,
38/// password: String,
39///
40/// model: String,
41/// method: String,
42/// args: Vec<Value>
43/// }
44/// ```
45///
46/// Then the following impls will be generated:
47/// ```ignore
48/// // The `Execute` is able to be used as JSON-RPC `params`
49/// impl JsonRpcParams for Execute {
50/// // Set the container; in this case, the container will use `describe` below
51/// // to implement a custom Serialize
52/// type Container<T> = OdooApiContainer<Self>;
53/// type Response = ExecuteResponse;
54///
55/// fn build(self) -> JsonRpcRequest<Self> { self._build() }
56/// }
57///
58/// // Which JSON-RPC service and method does `Execute` belong to?
59/// impl OdooApiMethod for Execute {
60/// fn describe(&self) -> (&'static str, &'static str) {
61/// ("object", "execute")
62/// }
63/// }
64///
65/// // Implement a method for this struct, so users can write `client.execute(...)`
66/// // Note that we specified "yes" for auth, so this impl is bound to `Authed`
67/// // clients only
68/// impl<I: RequestImpl> OdooClient<Authed, I> {
69/// pub fn execute(&self, model: &str, method: &str, args: Vec<Value>) -> OdooRequest<Execute, I> {
70/// let execute = Execute {
71/// // Auth info is pulled from the Client
72/// database: self.auth.database.clone(),
73/// uid: self.auth.uid,
74/// password: self.auth.password.clone(),
75///
76/// // Strings are passed as &str then converted to Strings
77/// model: model.into(),
78/// method: method.into(),
79/// args
80/// };
81///
82/// // Finally, build the request
83/// self.build_request(
84/// execute,
85/// &self.url_jsonrpc
86/// )
87/// }
88/// }
89/// ```
90#[proc_macro_attribute]
91pub fn odoo_api(args: TokenStream, input: TokenStream) -> TokenStream {
92 let args = parse_macro_input!(args);
93 let input = parse_macro_input!(input);
94
95 parse_result(odoo_api::odoo_api(args, input))
96}
97
98#[proc_macro_attribute]
99pub fn odoo_web(args: TokenStream, input: TokenStream) -> TokenStream {
100 let args = parse_macro_input!(args);
101 let input = parse_macro_input!(input);
102
103 parse_result(odoo_web::odoo_web(args, input))
104}
105
106#[proc_macro_attribute]
107pub fn odoo_orm(args: TokenStream, input: TokenStream) -> TokenStream {
108 let args = parse_macro_input!(args);
109 let input = parse_macro_input!(input);
110
111 parse_result(odoo_orm::odoo_orm(args, input))
112}
113
114#[proc_macro_derive(SerializeTuple)]
115pub fn serialize_tuple(input: TokenStream) -> TokenStream {
116 parse_result(serialize_tuple::serialize_tuple(input))
117}