borsh_derive/internals/attributes/
mod.rs

1use syn::{Attribute, Path};
2
3pub mod field;
4pub mod item;
5pub mod parsing;
6
7/// first field is attr name
8/// second field is its expected value format representation for error printing
9#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)]
10pub struct Symbol(pub &'static str, pub &'static str);
11
12/// borsh - top level prefix in nested meta attribute
13pub const BORSH: Symbol = Symbol("borsh", "borsh(...)");
14/// bound - sub-borsh nested meta, field-level only, `BorshSerialize` and `BorshDeserialize` contexts
15pub const BOUND: Symbol = Symbol("bound", "bound(...)");
16//  use_discriminant - sub-borsh nested meta, item-level only, enums only, `BorshSerialize` and `BorshDeserialize` contexts
17pub const USE_DISCRIMINANT: Symbol = Symbol("use_discriminant", "use_discriminant = ...");
18/// serialize - sub-bound nested meta attribute
19pub const SERIALIZE: Symbol = Symbol("serialize", "serialize = ...");
20/// deserialize - sub-bound nested meta attribute
21pub const DESERIALIZE: Symbol = Symbol("deserialize", "deserialize = ...");
22/// skip - sub-borsh nested meta, field-level only attribute, `BorshSerialize`, `BorshDeserialize`, `BorshSchema` contexts
23pub const SKIP: Symbol = Symbol("skip", "skip");
24/// init - sub-borsh nested meta, item-level only attribute  `BorshDeserialize` context
25pub const INIT: Symbol = Symbol("init", "init = ...");
26/// serialize_with - sub-borsh nested meta, field-level only, `BorshSerialize` context
27pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with", "serialize_with = ...");
28/// deserialize_with - sub-borsh nested meta, field-level only, `BorshDeserialize` context
29pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with", "deserialize_with = ...");
30/// crate - sub-borsh nested meta, item-level only, `BorshSerialize`, `BorshDeserialize`, `BorshSchema` contexts
31pub const CRATE: Symbol = Symbol("crate", "crate = ...");
32
33#[cfg(feature = "schema")]
34pub mod schema_keys {
35    use super::Symbol;
36
37    /// schema - sub-borsh nested meta, `BorshSchema` context
38    pub const SCHEMA: Symbol = Symbol("schema", "schema(...)");
39    /// params - sub-schema nested meta, field-level only attribute
40    pub const PARAMS: Symbol = Symbol("params", "params = ...");
41    /// serialize_with - sub-borsh nested meta, field-level only, `BorshSerialize` context
42    /// with_funcs - sub-schema nested meta, field-level only attribute
43    pub const WITH_FUNCS: Symbol = Symbol("with_funcs", "with_funcs(...)");
44    /// declaration - sub-with_funcs nested meta, field-level only attribute
45    pub const DECLARATION: Symbol = Symbol("declaration", "declaration = ...");
46    /// definitions - sub-with_funcs nested meta, field-level only attribute
47    pub const DEFINITIONS: Symbol = Symbol("definitions", "definitions = ...");
48}
49
50#[derive(Clone, Copy)]
51pub enum BoundType {
52    Serialize,
53    Deserialize,
54}
55impl PartialEq<Symbol> for Path {
56    fn eq(&self, word: &Symbol) -> bool {
57        self.is_ident(word.0)
58    }
59}
60
61impl<'a> PartialEq<Symbol> for &'a Path {
62    fn eq(&self, word: &Symbol) -> bool {
63        self.is_ident(word.0)
64    }
65}
66
67fn get_one_attribute(attrs: &[Attribute]) -> syn::Result<Option<&Attribute>> {
68    let count = attrs.iter().filter(|attr| attr.path() == BORSH).count();
69    let borsh = attrs.iter().find(|attr| attr.path() == BORSH);
70    if count > 1 {
71        return Err(syn::Error::new_spanned(
72            borsh.unwrap(),
73            format!("multiple `{}` attributes not allowed", BORSH.0),
74        ));
75    }
76    Ok(borsh)
77}