postgres_derive/
composites.rs

1use proc_macro2::Span;
2use syn::{
3    punctuated::Punctuated, Error, GenericParam, Generics, Ident, Path, PathSegment, Type,
4    TypeParamBound,
5};
6
7use crate::{case::RenameRule, overrides::Overrides};
8
9pub struct Field {
10    pub name: String,
11    pub ident: Ident,
12    pub type_: Type,
13}
14
15impl Field {
16    pub fn parse(raw: &syn::Field, rename_all: Option<RenameRule>) -> Result<Field, Error> {
17        let overrides = Overrides::extract(&raw.attrs, false)?;
18        let ident = raw.ident.as_ref().unwrap().clone();
19
20        // field level name override takes precendence over container level rename_all override
21        let name = match overrides.name {
22            Some(n) => n,
23            None => {
24                let name = ident.to_string();
25                let stripped = name.strip_prefix("r#").map(String::from).unwrap_or(name);
26
27                match rename_all {
28                    Some(rule) => rule.apply_to_field(&stripped),
29                    None => stripped,
30                }
31            }
32        };
33
34        Ok(Field {
35            name,
36            ident,
37            type_: raw.ty.clone(),
38        })
39    }
40}
41
42pub(crate) fn append_generic_bound(mut generics: Generics, bound: &TypeParamBound) -> Generics {
43    for param in &mut generics.params {
44        if let GenericParam::Type(param) = param {
45            param.bounds.push(bound.to_owned())
46        }
47    }
48    generics
49}
50
51pub(crate) fn new_derive_path(last: PathSegment) -> Path {
52    let mut path = Path {
53        leading_colon: None,
54        segments: Punctuated::new(),
55    };
56    path.segments
57        .push(Ident::new("postgres_types", Span::call_site()).into());
58    path.segments.push(last);
59    path
60}