• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Alorel / delegate-display-rs / 11550909325

28 Oct 2024 09:19AM UTC coverage: 93.118%. First build
11550909325

Pull #13

github

web-flow
Merge 90c44bead into e44b91622
Pull Request #13: deps: bump alorel-actions/cargo from 1 to 2

433 of 465 relevant lines covered (93.12%)

8.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.08
/src/implementation/main_field.rs
1
use super::dual_attr::AttrKind;
2
use crate::ATTR_ANY;
3
use macroific::prelude::*;
4
use proc_macro2::{Ident, Span, TokenStream};
5
use quote::ToTokens;
6
use std::fmt::Display;
7
use syn::punctuated::Punctuated;
8
use syn::spanned::Spanned;
9
use syn::{Error, LitInt, Type};
10

11
pub(crate) struct MainField {
12
    pub idx: usize,
13
    pub ident: Option<Ident>,
14
    pub ty: Type,
15
    pub num_fields: usize,
16
    pub mark: Option<AttrKind>,
17
}
18

19
impl MainField {
20
    pub fn ident_for_struct(&self) -> TokenStream {
10✔
21
        if let Some(ident) = &self.ident {
10✔
22
            ident.to_token_stream()
2✔
23
        } else {
24
            LitInt::new(itoa::Buffer::new().format(self.idx), Span::call_site()).into_token_stream()
8✔
25
        }
26
    }
10✔
27

28
    pub fn args_for_tuple_enum(&self) -> impl Iterator<Item = Ident> {
3✔
29
        fn empty_ident<T>(_: T) -> Ident {
1✔
30
            Ident::create("_")
1✔
31
        }
1✔
32

33
        let pre = (0..self.idx).map(empty_ident);
3✔
34
        let post = ((self.idx + 1)..self.num_fields).map(empty_ident);
3✔
35

3✔
36
        pre.chain(Some(Ident::create("v"))).chain(post)
3✔
37
    }
3✔
38

39
    pub fn resolve_from_fields(fields: syn::Fields, attr_name: &str) -> syn::Result<Option<Self>> {
19✔
40
        match fields {
19✔
41
            syn::Fields::Named(f) => {
5✔
42
                let span = f.span();
5✔
43
                Self::resolve_from_iter(f.named, attr_name, span)
5✔
44
            }
45
            syn::Fields::Unnamed(f) => {
12✔
46
                let span = f.span();
12✔
47
                Self::resolve_from_iter(f.unnamed, attr_name, span)
12✔
48
            }
49
            syn::Fields::Unit => Ok(None),
2✔
50
        }
51
    }
19✔
52

53
    pub fn resolve_from_iter<P>(
26✔
54
        fields: Punctuated<syn::Field, P>,
26✔
55
        attr_name: &str,
26✔
56
        span: Span,
26✔
57
    ) -> syn::Result<Option<Self>> {
26✔
58
        let num_fields = fields.len();
26✔
59
        let mut fields = fields.into_iter().enumerate();
26✔
60

61
        let mut first_field = match fields.next() {
26✔
62
            Some((idx, field)) => Self {
22✔
63
                num_fields,
22✔
64
                mark: AttrKind::aggregate(field.attrs, attr_name),
22✔
65
                idx,
22✔
66
                ident: field.ident,
22✔
67
                ty: field.ty,
22✔
68
            },
22✔
69
            None => return Ok(None),
4✔
70
        };
71

72
        for (idx, field) in fields {
32✔
73
            let span = field.span();
10✔
74

10✔
75
            match AttrKind::aggregate(field.attrs, attr_name) {
10✔
76
                None => {}
7✔
77
                Some(AttrKind::Primary) => match first_field.mark {
1✔
78
                    None | Some(AttrKind::CatchAll) => {
3✔
79
                        first_field.update(AttrKind::Primary, idx, field.ident, field.ty);
3✔
80
                    }
3✔
81
                    Some(AttrKind::Primary) => return Err(duplicate_err(attr_name, span)),
×
82
                },
83
                Some(AttrKind::CatchAll) => match first_field.mark {
×
84
                    None => {
×
85
                        first_field.update(AttrKind::CatchAll, idx, field.ident, field.ty);
×
86
                    }
×
87
                    Some(AttrKind::Primary) => {}
×
88
                    Some(AttrKind::CatchAll) => return Err(duplicate_err(ATTR_ANY, span)),
×
89
                },
90
            }
91
        }
92

93
        if num_fields > 1 && first_field.mark.is_none() {
22✔
94
            let msg = format!("At least one field must be marked with #[{attr_name}] or #[{ATTR_ANY}] on types with more than one field");
4✔
95
            Err(Error::new(span, msg))
4✔
96
        } else {
97
            Ok(Some(first_field))
18✔
98
        }
99
    }
26✔
100

101
    fn update(&mut self, mark: AttrKind, idx: usize, ident: Option<Ident>, ty: Type) {
3✔
102
        self.mark = Some(mark);
3✔
103
        self.idx = idx;
3✔
104
        self.ident = ident;
3✔
105
        self.ty = ty;
3✔
106
    }
3✔
107
}
108

109
fn duplicate_err<T>(attr_name: T, span: Span) -> Error
×
110
where
×
111
    T: Display,
×
112
{
×
113
    let msg = format!("Multiple fields marked with #[{attr_name}]");
×
114
    Error::new(span, msg)
×
115
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc