1#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
2#![allow(
3 clippy::cast_lossless,
4 clippy::manual_range_contains,
5 clippy::match_same_arms,
6 clippy::needless_pass_by_value,
7 clippy::uninlined_format_args,
8 clippy::unnecessary_wraps
9)]
10#![cfg_attr(all(test, exhaustive), feature(non_exhaustive_omitted_patterns_lint))]
11
12use proc_macro::TokenStream;
13use proc_macro2::{Ident, Literal, Span, TokenStream as TokenStream2};
14use quote::{quote, ToTokens};
15use std::mem;
16use syn::{parse_macro_input, Error, Lit, LitInt, Result};
17
18const K: usize = 6;
20
21#[allow(non_snake_case)]
22#[proc_macro]
23pub fn MustBe(input: TokenStream) -> TokenStream {
24 let lit = match ::syn::parse::<Lit>(input) {
::syn::__private::Ok(data) => data,
::syn::__private::Err(err) => {
return ::syn::__private::TokenStream::from(err.to_compile_error());
}
}parse_macro_input!(input as Lit);
25
26 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
27 let expanded = match lit {
28 Lit::Str(lit) => must_be_str(lit.value()),
29 Lit::Byte(lit) => must_be_byte(lit.value()),
30 Lit::Char(lit) => must_be_char(lit.value()),
31 Lit::Int(lit) => must_be_int(lit),
32 Lit::Bool(lit) => must_be_bool(lit.value),
33 Lit::ByteStr(_) | Lit::CStr(_) | Lit::Float(_) | Lit::Verbatim(_) => unsupported(lit),
34 _ => unsupported(lit),
35 };
36
37 expanded.unwrap_or_else(Error::into_compile_error).into()
38}
39
40enum StrNode {
65 Char(char),
66 Tuple(Vec<StrNode>),
67}
68
69impl ToTokens for StrNode {
70 fn to_tokens(&self, tokens: &mut TokenStream2) {
71 tokens.extend(match self {
72 StrNode::Char(ch) => {
73 if let 'A'..='Z' | 'a'..='z' = ch {
74 let mut buf = [0];
75 let name = ch.encode_utf8(&mut buf);
76 let ident = Ident::new(name, Span::call_site());
77 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "alphabet");
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&ident, &mut _s);
_s
}quote!(::monostate::alphabet::#ident)
78 } else {
79 match ch.len_utf8() {
80 1 => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "alphabet");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "char");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&ch, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::alphabet::char<#ch>),
81 2 => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "alphabet");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "two");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "char");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&ch, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::alphabet::two::char<#ch>),
82 3 => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "alphabet");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "three");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "char");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&ch, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::alphabet::three::char<#ch>),
83 4 => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "alphabet");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "four");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "char");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&ch, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::alphabet::four::char<#ch>),
84 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
85 }
86 }
87 }
88 StrNode::Tuple(vec) => {
89 let len = vec.len();
90 if !(len >= 2 && len <= K) {
{ ::core::panicking::panic_fmt(format_args!("len={0}", len)); }
};assert!(len >= 2 && len <= K, "len={}", len);
91 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _i = 0usize;
let has_iter =
::quote::__private::ThereIsNoIteratorInRepetition;
#[allow(unused_mut)]
let (mut vec, i) = vec.quote_into_iter();
let has_iter = has_iter | i;
let _: ::quote::__private::HasIterator = has_iter;
while true {
let vec =
match vec.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if _i > 0 { ::quote::__private::push_comma(&mut _s); }
_i += 1;
::quote::ToTokens::to_tokens(&vec, &mut _s);
}
}
_s
});
_s
}quote!((#(#vec),*))
92 }
93 });
94 }
95}
96
97fn must_be_str(value: String) -> Result<TokenStream2> {
98 if value.is_empty() {
99 return Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeStr");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "alphabet");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "len");
::quote::__private::push_lt(&mut _s);
::quote::__private::parse(&mut _s, "0");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_comma(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
});
::quote::__private::push_gt(&mut _s);
_s
}quote! {
100 ::monostate::MustBeStr::<(::monostate::alphabet::len<0>, ())>
101 });
102 }
103 let mut nodes = Vec::new();
104 for ch in value.chars() {
105 nodes.push(StrNode::Char(ch));
106 }
107 let mut pow = 1;
109 while pow * K < nodes.len() {
110 pow *= K;
111 }
112 while nodes.len() > 1 {
113 let overage = nodes.len() - pow;
115 let num_tuple_nodes = (overage + K - 2) / (K - 1);
120 let mut remainder = num_tuple_nodes + overage;
122 let mut read = nodes.len() - remainder;
124 let mut write = read;
126 let mut make_tuple = true;
128 while let Some(node) = nodes.get_mut(read) {
129 let next = mem::replace(node, StrNode::Char('\0'));
130 if make_tuple {
131 nodes[write] = StrNode::Tuple(Vec::with_capacity(K));
132 }
133 if let StrNode::Tuple(vec) = &mut nodes[write] {
134 vec.push(next);
135 } else {
136 ::core::panicking::panic("internal error: entered unreachable code");unreachable!();
137 }
138 remainder -= 1;
139 make_tuple = remainder % K == 0;
140 write += make_tuple as usize;
141 read += 1;
142 }
143 nodes.truncate(pow);
144 pow /= K;
145 }
146 let len = Literal::usize_unsuffixed(value.len());
147 let encoded = &nodes[0];
148 Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeStr");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "alphabet");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "len");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&len, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&encoded, &mut _s);
_s
});
::quote::__private::push_gt(&mut _s);
_s
}quote! {
149 ::monostate::MustBeStr::<(::monostate::alphabet::len<#len>, #encoded)>
150 })
151}
152
153fn must_be_byte(value: u8) -> Result<TokenStream2> {
154 Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeU8");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&value, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeU8::<#value>))
155}
156
157fn must_be_char(value: char) -> Result<TokenStream2> {
158 Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeChar");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&value, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeChar::<#value>))
159}
160
161fn must_be_int(lit: LitInt) -> Result<TokenStream2> {
162 let token = lit.token();
163 match lit.suffix() {
164 "u8" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeU8");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeU8::<#token>)),
165 "u16" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeU16");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeU16::<#token>)),
166 "u32" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeU32");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeU32::<#token>)),
167 "u64" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeU64");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeU64::<#token>)),
168 "u128" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeU128");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeU128::<#token>)),
169 "i8" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeI8");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeI8::<#token>)),
170 "i16" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeI16");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeI16::<#token>)),
171 "i32" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeI32");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeI32::<#token>)),
172 "i64" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeI64");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeI64::<#token>)),
173 "i128" => Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeI128");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeI128::<#token>)),
174 "" => {
175 if lit.base10_digits().starts_with('-') {
176 Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeNegInt");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeNegInt::<#token>))
177 } else {
178 Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBePosInt");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&token, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBePosInt::<#token>))
179 }
180 }
181 suffix @ ("usize" | "isize") => {
182 let msg = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("serde data model only uses consistently sized integer types, not {0}",
suffix))
})format!(
183 "serde data model only uses consistently sized integer types, not {}",
184 suffix,
185 );
186 Err(Error::new(lit.span(), msg))
187 }
188 suffix => {
189 let msg = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unsupported integers suffix `{0}`",
suffix))
})format!("unsupported integers suffix `{}`", suffix);
190 Err(Error::new(lit.span(), msg))
191 }
192 }
193}
194
195fn must_be_bool(value: bool) -> Result<TokenStream2> {
196 Ok({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "monostate");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MustBeBool");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&value, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::monostate::MustBeBool::<#value>))
197}
198
199fn unsupported(lit: Lit) -> Result<TokenStream2> {
200 Err(Error::new(lit.span(), "unsupported monostate literal kind"))
201}