1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use proc_macro2::{Span, TokenStream};
use syn::punctuated::Punctuated;
use syn::{Generics, Ident, Type, WhereClause};

pub fn bundle_impl(
    trait_name: &str,
    type_name: Ident,
    internal: bool,
    block: TokenStream,
) -> TokenStream {
    let const_name = Ident::new(
        &format!("_palette_derive_{}_for_{}", trait_name, type_name),
        Span::call_site(),
    );

    if internal {
        quote!{
            #[allow(non_snake_case, unused_attributes, unused_qualifications)]
            mod #const_name {
                extern crate num_traits as _num_traits;
                use super::*;
                #block
            }
        }
    } else {
        quote!{
            #[allow(non_snake_case, unused_attributes, unused_qualifications)]
            mod #const_name {
                extern crate palette as _palette;
                extern crate num_traits as _num_traits;
                use super::*;
                #block
            }
        }
    }
}

pub fn path(path: &[&str], internal: bool) -> TokenStream {
    let path = path
        .into_iter()
        .map(|&ident| Ident::new(ident, Span::call_site()));

    if internal {
        quote!{::#(#path)::*}
    } else {
        quote!{self::_palette::#(#path)::*}
    }
}

pub fn path_type(path: &[&str], internal: bool) -> Type {
    let path = path
        .into_iter()
        .map(|&ident| Ident::new(ident, Span::call_site()));

    if internal {
        parse_quote!{::#(#path)::*}
    } else {
        parse_quote!{self::_palette::#(#path)::*}
    }
}

pub fn color_path(color: &str, internal: bool) -> TokenStream {
    match color {
        "Luma" => path(&["luma", "Luma"], internal),
        "Rgb" => path(&["rgb", "Rgb"], internal),
        _ => path(&[color], internal),
    }
}

pub fn add_missing_where_clause(generics: &mut Generics) {
    if generics.where_clause.is_none() {
        generics.where_clause = Some(WhereClause {
            where_token: Token![where](Span::call_site()),
            predicates: Punctuated::new(),
        })
    }
}