aranya_capi_codegen/
attr.rs1use std::{fmt, iter::Iterator};
4
5use proc_macro2::TokenStream;
6use quote::ToTokens;
7use syn::{spanned::Spanned, Error, Ident, Path};
8
9#[derive(Copy, Clone)]
11pub struct Symbol(pub &'static str);
12
13impl PartialEq<Symbol> for Ident {
14 fn eq(&self, word: &Symbol) -> bool {
15 self == word.0
16 }
17}
18
19impl PartialEq<Symbol> for &Ident {
20 fn eq(&self, word: &Symbol) -> bool {
21 *self == word.0
22 }
23}
24
25impl PartialEq<Symbol> for Path {
26 fn eq(&self, word: &Symbol) -> bool {
27 PartialEq::eq(&self, word)
28 }
29}
30
31impl PartialEq<Symbol> for &Path {
32 fn eq(&self, word: &Symbol) -> bool {
33 Iterator::eq(
34 self.segments.iter().map(|seg| &seg.ident),
35 word.0.split("::"),
36 )
37 }
38}
39
40impl fmt::Display for Symbol {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 write!(f, "{}", self.0)
43 }
44}
45
46pub struct Attr<T> {
48 name: Symbol,
49 tokens: TokenStream,
50 value: Option<T>,
51}
52
53impl<T> Attr<T> {
54 pub fn none(name: Symbol) -> Self {
56 Self {
57 name,
58 tokens: TokenStream::new(),
59 value: None,
60 }
61 }
62
63 pub fn set<A: ToTokens>(&mut self, obj: A, value: T) -> syn::Result<()> {
65 let tokens = obj.into_token_stream();
66 if self.value.is_some() {
67 Err(Error::new(
68 tokens.span(),
69 format!("duplicate value: {}", self.name),
70 ))
71 } else {
72 self.tokens = tokens;
73 self.value = Some(value);
74 Ok(())
75 }
76 }
77
78 pub fn get(self) -> Option<T> {
80 self.value
81 }
82}