diff --git a/Cargo.toml b/Cargo.toml index e0b7388..595c444 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ derive = ["bincode_derive"] bincode_derive = { path = "derive", version = "2.0.0-dev", optional = true } serde = { version = "1.0.130", optional = true } -# Used for derive tests +# Used for tests [dev-dependencies] serde_derive = "1.0.130" serde_json = "1.0.68" diff --git a/derive/src/error.rs b/derive/src/error.rs index 724c372..b44dcda 100644 --- a/derive/src/error.rs +++ b/derive/src/error.rs @@ -1,4 +1,4 @@ -use crate::prelude::*; +use crate::{generate::StreamBuilder, prelude::*}; use std::fmt; #[derive(Debug)] @@ -44,27 +44,13 @@ impl Error { pub fn throw_with_span(self, span: Span) -> TokenStream { // compile_error!($message) - vec![ - TokenTree::Ident(Ident::new("compile_error", span)), - TokenTree::Punct({ - let mut punct = Punct::new('!', Spacing::Alone); - punct.set_span(span); - punct - }), - TokenTree::Group({ - let mut group = Group::new(Delimiter::Brace, { - TokenTree::Literal({ - let mut string = Literal::string(&self.to_string()); - string.set_span(span); - string - }) - .into() - }); - group.set_span(span); - group - }), - ] - .into_iter() - .collect() + let mut builder = StreamBuilder::new(); + builder.ident_str("compile_error"); + builder.punct('!'); + builder.group(Delimiter::Brace, |b| { + b.lit_str(self.to_string()); + }); + builder.set_span_on_all_tokens(span); + builder.stream } } diff --git a/derive/src/generate/generate_fn.rs b/derive/src/generate/generate_fn.rs index 53428ca..b42b658 100644 --- a/derive/src/generate/generate_fn.rs +++ b/derive/src/generate/generate_fn.rs @@ -1,7 +1,9 @@ use super::{ImplFor, StreamBuilder}; use crate::prelude::Delimiter; + +/// A builder for functions. pub struct FnBuilder<'a, 'b> { - generate: &'b mut ImplFor<'a>, + generate: Option<&'b mut ImplFor<'a>>, name: String, lifetime_and_generics: Vec<(String, Vec)>, @@ -13,7 +15,7 @@ pub struct FnBuilder<'a, 'b> { impl<'a, 'b> FnBuilder<'a, 'b> { pub(super) fn new(generate: &'b mut ImplFor<'a>, name: impl Into) -> Self { Self { - generate, + generate: Some(generate), name: name.into(), lifetime_and_generics: Vec::new(), self_arg: FnSelfArg::None, @@ -22,6 +24,30 @@ impl<'a, 'b> FnBuilder<'a, 'b> { } } + #[cfg(test)] + #[doc(hidden)] + #[allow(unused)] + pub fn for_test() -> Self { + Self { + generate: None, + name: String::new(), + lifetime_and_generics: Vec::new(), + self_arg: FnSelfArg::None, + args: Vec::new(), + return_type: None, + } + } + + /// Add a generic parameter. Keep in mind that this is *not* a valid lifetime. + /// + /// `dependencies` are the optional dependencies of the parameter. + /// + /// ```ignore + /// let mut builder: FnBuilder = ...; + /// builder + /// .with_generic("D", None) // fn Foo() + /// .with_generic("E", &["Encodable"]); // fn foo(); + /// ``` pub fn with_generic(mut self, name: T, dependencies: U) -> Self where T: Into, @@ -52,7 +78,7 @@ impl<'a, 'b> FnBuilder<'a, 'b> { pub fn body(self, body_builder: impl FnOnce(&mut StreamBuilder)) { let FnBuilder { - generate, + mut generate, name, lifetime_and_generics, self_arg, @@ -108,9 +134,10 @@ impl<'a, 'b> FnBuilder<'a, 'b> { builder.push_parsed(&return_type); } - generate.group.append(builder); + let generator = generate.take().unwrap(); - generate.group.group(Delimiter::Brace, body_builder); + generator.group.append(builder); + generator.group.group(Delimiter::Brace, body_builder); } } diff --git a/derive/src/generate/stream_builder.rs b/derive/src/generate/stream_builder.rs index a1a0854..8331286 100644 --- a/derive/src/generate/stream_builder.rs +++ b/derive/src/generate/stream_builder.rs @@ -6,7 +6,7 @@ use std::str::FromStr; #[must_use] #[derive(Default)] pub struct StreamBuilder { - pub(super) stream: TokenStream, + pub(crate) stream: TokenStream, } impl StreamBuilder { @@ -83,6 +83,11 @@ impl StreamBuilder { ]); } + pub fn lit_str(&mut self, str: impl AsRef) { + self.stream + .extend([TokenTree::Literal(Literal::string(str.as_ref()))]); + } + pub fn lit_u32(&mut self, val: u32) { self.stream .extend([TokenTree::Literal(Literal::u32_unsuffixed(val))]); @@ -92,4 +97,14 @@ impl StreamBuilder { self.stream .extend([TokenTree::Literal(Literal::usize_unsuffixed(val))]); } + + pub fn set_span_on_all_tokens(&mut self, span: Span) { + self.stream = std::mem::take(&mut self.stream) + .into_iter() + .map(|mut token| { + token.set_span(span); + token + }) + .collect(); + } } diff --git a/src/config.rs b/src/config.rs index 4cd83c6..dd2d3b9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -47,7 +47,7 @@ pub struct Configuration } impl Configuration { - /// The default config. By default this will be: + /// The default config for bincode 2.0. By default this will be: /// - Little endian /// - Variable int encoding /// - Skip fixed array length