logo
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#![doc(html_favicon_url = "https://www.ruma.io/favicon.ico")]
#![doc(html_logo_url = "https://www.ruma.io/images/logo.png")]

use proc_macro::TokenStream;
use quote::quote;
use ruma_identifiers_validation::{
    device_key_id, event_id, key_id, mxc_uri, room_alias_id, room_id, room_version_id, server_name,
    user_id,
};
use syn::{parse::Parse, parse_macro_input, LitStr, Path, Token};

struct Input {
    dollar_crate: Path,
    id: LitStr,
}

impl Parse for Input {
    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
        let dollar_crate = input.parse()?;
        let _: Token![,] = input.parse()?;
        let id = input.parse()?;

        Ok(Self { dollar_crate, id })
    }
}

#[proc_macro]
pub fn device_key_id(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(device_key_id::validate(&id.value()).is_ok(), "Invalid device key id");

    let output = quote! {
        <&#dollar_crate::DeviceKeyId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
    };

    output.into()
}

#[proc_macro]
pub fn event_id(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(event_id::validate(&id.value()).is_ok(), "Invalid event id");

    let output = quote! {
        <&#dollar_crate::EventId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
    };

    output.into()
}

#[proc_macro]
pub fn room_alias_id(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(room_alias_id::validate(&id.value()).is_ok(), "Invalid room_alias_id");

    let output = quote! {
        <&#dollar_crate::RoomAliasId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
    };

    output.into()
}

#[proc_macro]
pub fn room_id(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(room_id::validate(&id.value()).is_ok(), "Invalid room_id");

    let output = quote! {
        <&#dollar_crate::RoomId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
    };

    output.into()
}

#[proc_macro]
pub fn room_version_id(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(room_version_id::validate(&id.value()).is_ok(), "Invalid room_version_id");

    let output = quote! {
        <#dollar_crate::RoomVersionId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
    };

    output.into()
}

#[proc_macro]
pub fn server_signing_key_id(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(key_id::validate(&id.value()).is_ok(), "Invalid server_signing_key_id");

    let output = quote! {
        <&#dollar_crate::ServerSigningKeyId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
    };

    output.into()
}

#[proc_macro]
pub fn server_name(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(server_name::validate(&id.value()).is_ok(), "Invalid server_name");

    let output = quote! {
        <&#dollar_crate::ServerName as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
    };

    output.into()
}

#[proc_macro]
pub fn mxc_uri(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(mxc_uri::validate(&id.value()).is_ok(), "Invalid mxc://");

    let output = quote! {
        <&#dollar_crate::MxcUri as ::std::convert::From<&str>>::from(#id)
    };

    output.into()
}

#[proc_macro]
pub fn user_id(input: TokenStream) -> TokenStream {
    let Input { dollar_crate, id } = parse_macro_input!(input as Input);
    assert!(user_id::validate(&id.value()).is_ok(), "Invalid user_id");

    let output = quote! {
        <&#dollar_crate::UserId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
    };

    output.into()
}