1use crate::token::*;
2use crate::TokenSink;
3
4pub trait IntoTokens {
6 fn into_tokens<S: TokenSink>(&self, sink: &mut S) -> Result<(), S::Error>;
10}
11
12macro_rules! basic_into_tokens [
13 ($($id:ident => $ty:ty),*$(,)?) => {
14 $(impl IntoTokens for $ty {
15 fn into_tokens<S: TokenSink>(&self, sink: &mut S) -> Result<(), S::Error> {
16 sink.yield_token(Token::$id(*self)).map(|_| ())
17 }
18 })*
19 };
20];
21
22basic_into_tokens![
23 Bool => bool,
24
25 U8 => u8,
26 U16 => u16,
27 U32 => u32,
28 U64 => u64,
29 U128 => u128,
30 Usize => usize,
31
32 I8 => i8,
33 I16 => i16,
34 I32 => i32,
35 I64 => i64,
36 I128 => i128,
37 Isize => isize,
38
39 F32 => f32,
40 F64 => f64,
41 Char => char,
42 Bytes => &'_ [u8],
43 Str => &'_ str,
44];
45
46impl IntoTokens for () {
47 fn into_tokens<S: TokenSink>(&self, sink: &mut S) -> Result<(), S::Error> {
48 sink.yield_token(Token::Unit).map(|_| ())
49 }
50}
51
52impl<'a, K, V> IntoTokens for (K, V)
53where
54 K: IntoTokens,
55 V: IntoTokens,
56{
57 fn into_tokens<S: TokenSink>(&self, sink: &mut S) -> Result<(), S::Error> {
58 sink.yield_token(Token::Tuple(TupleMeta { size_hint: Some(2) }))?;
59 self.0.into_tokens(sink)?;
60 self.1.into_tokens(sink)?;
61 sink.yield_token(Token::EndTuple).map(|_| ())
62 }
63}
64
65impl<T> IntoTokens for [T]
66where
67 T: IntoTokens,
68{
69 fn into_tokens<S: TokenSink>(&self, sink: &mut S) -> Result<(), S::Error> {
70 iter_into_tokens(self.iter(), sink).map(|_| ())
71 }
72}
73
74impl<T> IntoTokens for Vec<T>
75where
76 T: IntoTokens,
77{
78 fn into_tokens<S: TokenSink>(&self, sink: &mut S) -> Result<(), S::Error> {
79 iter_into_tokens(self.iter(), sink).map(|_| ())
80 }
81}
82
83pub fn iter_into_tokens<'a, I: Iterator<Item = &'a T>, S: TokenSink, T>(
85 it: I,
86 sink: &mut S,
87) -> Result<(), S::Error>
88where
89 T: 'a + IntoTokens,
90{
91 let (_, size_hint) = it.size_hint();
92 sink.yield_token(Token::Seq(SeqMeta { size_hint }))?;
93
94 for elem in it {
95 elem.into_tokens(sink)?;
96 }
97
98 sink.yield_token(Token::EndSeq).map(|_| ())
99}
100
101impl<'a> IntoTokens for Token<'a> {
102 fn into_tokens<S: TokenSink>(&self, sink: &mut S) -> Result<(), S::Error> {
103 sink.yield_token(self.clone())?;
104 Ok(())
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111 use crate::vec::*;
112
113 #[test]
114 fn test_bool_into() {
115 let mut got = TokenVec::new();
116 true.into_tokens(&mut got).unwrap();
117 assert_eq!(got.into_vec(), vec![OwningToken::Bool(true)]);
118 }
119
120 #[test]
121 fn test_u32_into() {
122 let mut got = TokenVec::new();
123 42u32.into_tokens(&mut got).unwrap();
124 assert_eq!(got.into_vec(), vec![OwningToken::U32(42)]);
125 }
126
127 #[test]
128 fn test_tuple_into() {
129 let mut got = TokenVec::new();
130 (42u32, true).into_tokens(&mut got).unwrap();
131 assert_eq!(
132 got.into_vec(),
133 vec![
134 OwningToken::Tuple(TupleMeta { size_hint: Some(2) }),
135 OwningToken::U32(42),
136 OwningToken::Bool(true),
137 OwningToken::EndTuple,
138 ]
139 );
140 }
141
142 #[test]
143 fn test_vec_u32_into() {
144 let mut got = TokenVec::new();
145 vec![42u32].into_tokens(&mut got).unwrap();
146 assert_eq!(
147 got.into_vec(),
148 vec![
149 OwningToken::Seq(SeqMeta { size_hint: Some(1) }),
150 OwningToken::U32(42),
151 OwningToken::EndSeq,
152 ],
153 );
154 }
155}