|
1 |
| -extern crate proc_macro; |
2 |
| - |
3 |
| -mod buffer; |
4 |
| -mod bytecode; |
| 1 | +//! This crate provides Serde's two derive macros. |
| 2 | +//! |
| 3 | +//! ```edition2021 |
| 4 | +//! # use serde_derive::{Deserialize, Serialize}; |
| 5 | +//! # |
| 6 | +//! #[derive(Serialize, Deserialize)] |
| 7 | +//! # struct S; |
| 8 | +//! # |
| 9 | +//! # fn main() {} |
| 10 | +//! ``` |
| 11 | +//! |
| 12 | +//! Please refer to [https://serde.rs/derive.html] for how to set this up. |
| 13 | +//! |
| 14 | +//! [https://serde.rs/derive.html]: https://serde.rs/derive.html |
| 15 | +
|
| 16 | +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.171")] |
| 17 | +#![allow(unknown_lints, bare_trait_objects)] |
5 | 18 |
|
6 |
| -use crate::buffer::{InputBuffer, OutputBuffer}; |
7 |
| -use crate::bytecode::Bytecode; |
8 |
| -use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; |
9 |
| -use std::io::{Read, Write}; |
10 |
| -use std::iter::FromIterator; |
11 |
| -use std::process::{Command, Stdio}; |
12 |
| -use std::str::FromStr; |
| 19 | +extern crate proc_macro; |
13 | 20 |
|
14 | 21 | #[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))]
|
15 |
| -compile_error! { |
16 |
| - "this proof of concept is only compiled for x86_64-unknown-linux-gnu" |
17 |
| -} |
18 |
| - |
19 |
| -#[proc_macro_derive(Serialize, attributes(serde))] |
20 |
| -pub fn derive_serialize(input: TokenStream) -> TokenStream { |
21 |
| - derive(0, input) |
22 |
| -} |
23 |
| - |
24 |
| -#[proc_macro_derive(Deserialize, attributes(serde))] |
25 |
| -pub fn derive_deserialize(input: TokenStream) -> TokenStream { |
26 |
| - derive(1 + cfg!(feature = "deserialize_in_place") as u8, input) |
27 |
| -} |
28 |
| - |
29 |
| -fn derive(select: u8, input: TokenStream) -> TokenStream { |
30 |
| - let mut memory = TokenMemory::default(); |
31 |
| - let mut buf = OutputBuffer::new(); |
32 |
| - buf.write_u8(select); |
33 |
| - |
34 |
| - memory.spans.push(Span::call_site()); |
35 |
| - for token in input { |
36 |
| - memory.linearize_token(token, &mut buf); |
37 |
| - } |
38 |
| - |
39 |
| - let path = concat!( |
40 |
| - env!("CARGO_MANIFEST_DIR"), |
41 |
| - "/serde_derive-x86_64-unknown-linux-gnu", |
42 |
| - ); |
43 |
| - let mut child = Command::new(path) |
44 |
| - .stdin(Stdio::piped()) |
45 |
| - .stdout(Stdio::piped()) |
46 |
| - .spawn() |
47 |
| - .expect("failed to spawn process"); |
48 |
| - |
49 |
| - let mut stdin = child.stdin.take().unwrap(); |
50 |
| - let mut buf = buf.into_bytes(); |
51 |
| - stdin.write_all(&buf).unwrap(); |
52 |
| - drop(stdin); |
53 |
| - |
54 |
| - let mut stdout = child.stdout.take().unwrap(); |
55 |
| - buf.clear(); |
56 |
| - stdout.read_to_end(&mut buf).unwrap(); |
57 |
| - |
58 |
| - let mut buf = InputBuffer::new(&buf); |
59 |
| - memory.receive(&mut buf) |
60 |
| -} |
61 |
| - |
62 |
| -#[derive(Default)] |
63 |
| -struct TokenMemory { |
64 |
| - spans: Vec<Span>, |
65 |
| - groups: Vec<Group>, |
66 |
| - idents: Vec<Ident>, |
67 |
| - puncts: Vec<Punct>, |
68 |
| - literals: Vec<Literal>, |
69 |
| -} |
70 |
| - |
71 |
| -enum Kind { |
72 |
| - Group(Delimiter), |
73 |
| - Ident, |
74 |
| - Punct(Spacing), |
75 |
| - Literal, |
76 |
| -} |
77 |
| - |
78 |
| -impl TokenMemory { |
79 |
| - // Depth-first post-order traversal. |
80 |
| - fn linearize_token(&mut self, token: TokenTree, buf: &mut OutputBuffer) { |
81 |
| - match token { |
82 |
| - TokenTree::Group(group) => { |
83 |
| - let mut len = 0usize; |
84 |
| - for token in group.stream() { |
85 |
| - self.linearize_token(token, buf); |
86 |
| - len += 1; |
87 |
| - } |
88 |
| - assert!(len <= u32::MAX as usize); |
89 |
| - buf.write_u8(match group.delimiter() { |
90 |
| - Delimiter::Parenthesis => Bytecode::GROUP_PARENTHESIS, |
91 |
| - Delimiter::Brace => Bytecode::GROUP_BRACE, |
92 |
| - Delimiter::Bracket => Bytecode::GROUP_BRACKET, |
93 |
| - Delimiter::None => Bytecode::GROUP_NONE, |
94 |
| - }); |
95 |
| - buf.write_u32(len as u32); |
96 |
| - self.spans |
97 |
| - .extend([group.span(), group.span_open(), group.span_close()]); |
98 |
| - self.groups.push(group); |
99 |
| - } |
100 |
| - TokenTree::Ident(ident) => { |
101 |
| - buf.write_u8(Bytecode::IDENT); |
102 |
| - let repr = ident.to_string(); |
103 |
| - assert!(repr.len() <= u16::MAX as usize); |
104 |
| - buf.write_u16(repr.len() as u16); |
105 |
| - buf.write_str(&repr); |
106 |
| - self.spans.push(ident.span()); |
107 |
| - self.idents.push(ident); |
108 |
| - } |
109 |
| - TokenTree::Punct(punct) => { |
110 |
| - buf.write_u8(match punct.spacing() { |
111 |
| - Spacing::Alone => Bytecode::PUNCT_ALONE, |
112 |
| - Spacing::Joint => Bytecode::PUNCT_JOINT, |
113 |
| - }); |
114 |
| - let ch = punct.as_char(); |
115 |
| - assert!(ch.is_ascii()); |
116 |
| - buf.write_u8(ch as u8); |
117 |
| - self.spans.push(punct.span()); |
118 |
| - self.puncts.push(punct); |
119 |
| - } |
120 |
| - TokenTree::Literal(literal) => { |
121 |
| - buf.write_u8(Bytecode::LITERAL); |
122 |
| - let repr = literal.to_string(); |
123 |
| - assert!(repr.len() <= u16::MAX as usize); |
124 |
| - buf.write_u16(repr.len() as u16); |
125 |
| - buf.write_str(&repr); |
126 |
| - self.spans.push(literal.span()); |
127 |
| - self.literals.push(literal); |
128 |
| - } |
129 |
| - } |
130 |
| - } |
131 |
| - |
132 |
| - fn receive(&self, buf: &mut InputBuffer) -> TokenStream { |
133 |
| - let mut trees = Vec::new(); |
134 |
| - while !buf.is_empty() { |
135 |
| - match match buf.read_u8() { |
136 |
| - Bytecode::GROUP_PARENTHESIS => Kind::Group(Delimiter::Parenthesis), |
137 |
| - Bytecode::GROUP_BRACE => Kind::Group(Delimiter::Brace), |
138 |
| - Bytecode::GROUP_BRACKET => Kind::Group(Delimiter::Bracket), |
139 |
| - Bytecode::GROUP_NONE => Kind::Group(Delimiter::None), |
140 |
| - Bytecode::IDENT => Kind::Ident, |
141 |
| - Bytecode::PUNCT_ALONE => Kind::Punct(Spacing::Alone), |
142 |
| - Bytecode::PUNCT_JOINT => Kind::Punct(Spacing::Joint), |
143 |
| - Bytecode::LITERAL => Kind::Literal, |
144 |
| - Bytecode::LOAD_GROUP => { |
145 |
| - let identity = buf.read_u32(); |
146 |
| - let group = self.groups[identity as usize].clone(); |
147 |
| - trees.push(TokenTree::Group(group)); |
148 |
| - continue; |
149 |
| - } |
150 |
| - Bytecode::LOAD_IDENT => { |
151 |
| - let identity = buf.read_u32(); |
152 |
| - let ident = self.idents[identity as usize].clone(); |
153 |
| - trees.push(TokenTree::Ident(ident)); |
154 |
| - continue; |
155 |
| - } |
156 |
| - Bytecode::LOAD_PUNCT => { |
157 |
| - let identity = buf.read_u32(); |
158 |
| - let punct = self.puncts[identity as usize].clone(); |
159 |
| - trees.push(TokenTree::Punct(punct)); |
160 |
| - continue; |
161 |
| - } |
162 |
| - Bytecode::LOAD_LITERAL => { |
163 |
| - let identity = buf.read_u32(); |
164 |
| - let literal = self.literals[identity as usize].clone(); |
165 |
| - trees.push(TokenTree::Literal(literal)); |
166 |
| - continue; |
167 |
| - } |
168 |
| - Bytecode::SET_SPAN => { |
169 |
| - trees.last_mut().unwrap().set_span(self.read_span(buf)); |
170 |
| - continue; |
171 |
| - } |
172 |
| - _ => unreachable!(), |
173 |
| - } { |
174 |
| - Kind::Group(delimiter) => { |
175 |
| - let len = buf.read_u32(); |
176 |
| - let stream = trees.drain(trees.len() - len as usize..).collect(); |
177 |
| - let group = Group::new(delimiter, stream); |
178 |
| - trees.push(TokenTree::Group(group)); |
179 |
| - } |
180 |
| - Kind::Ident => { |
181 |
| - let len = buf.read_u16(); |
182 |
| - let repr = buf.read_str(len as usize); |
183 |
| - let span = self.read_span(buf); |
184 |
| - let ident = if let Some(repr) = repr.strip_prefix("r#") { |
185 |
| - Ident::new_raw(repr, span) |
186 |
| - } else { |
187 |
| - Ident::new(repr, span) |
188 |
| - }; |
189 |
| - trees.push(TokenTree::Ident(ident)); |
190 |
| - } |
191 |
| - Kind::Punct(spacing) => { |
192 |
| - let ch = buf.read_u8(); |
193 |
| - assert!(ch.is_ascii()); |
194 |
| - let punct = Punct::new(ch as char, spacing); |
195 |
| - trees.push(TokenTree::Punct(punct)); |
196 |
| - } |
197 |
| - Kind::Literal => { |
198 |
| - let len = buf.read_u16(); |
199 |
| - let repr = buf.read_str(len as usize); |
200 |
| - let literal = Literal::from_str(repr).unwrap(); |
201 |
| - trees.push(TokenTree::Literal(literal)); |
202 |
| - } |
203 |
| - } |
204 |
| - } |
205 |
| - |
206 |
| - TokenStream::from_iter(trees) |
207 |
| - } |
| 22 | +include!("lib_from_source.rs"); |
208 | 23 |
|
209 |
| - fn read_span(&self, buf: &mut InputBuffer) -> Span { |
210 |
| - let lo = buf.read_u32(); |
211 |
| - let hi = buf.read_u32(); |
212 |
| - let span = self.spans[lo as usize]; |
213 |
| - if lo == hi { |
214 |
| - span |
215 |
| - } else { |
216 |
| - #[cfg(any())] // FIXME |
217 |
| - return span.join(self.spans[hi as usize]).unwrap_or(span); |
218 |
| - span |
219 |
| - } |
220 |
| - } |
221 |
| -} |
| 24 | +#[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))] |
| 25 | +include!("lib_precompiled.rs"); |
0 commit comments