mirror of https://git.sr.ht/~stygianentity/bincode
Removed a panic in the derive/src/generate module, moved it to derive/src/derive_* instead
This commit is contained in:
parent
baad206c6c
commit
435e030182
|
|
@ -15,6 +15,7 @@ impl DeriveEnum {
|
||||||
|
|
||||||
generator
|
generator
|
||||||
.impl_for("bincode::enc::Encode")
|
.impl_for("bincode::enc::Encode")
|
||||||
|
.unwrap()
|
||||||
.generate_fn("encode")
|
.generate_fn("encode")
|
||||||
.with_generic("E", ["bincode::enc::Encoder"])
|
.with_generic("E", ["bincode::enc::Encoder"])
|
||||||
.with_self_arg(FnSelfArg::RefSelf)
|
.with_self_arg(FnSelfArg::RefSelf)
|
||||||
|
|
@ -64,20 +65,23 @@ impl DeriveEnum {
|
||||||
body.push_parsed(format!(
|
body.push_parsed(format!(
|
||||||
"<u32 as bincode::enc::Encode>::encode(&{}, &mut encoder)?;",
|
"<u32 as bincode::enc::Encode>::encode(&{}, &mut encoder)?;",
|
||||||
variant_index
|
variant_index
|
||||||
));
|
))
|
||||||
|
.unwrap();
|
||||||
// If we have any fields, encode them all one by one
|
// If we have any fields, encode them all one by one
|
||||||
for field_name in variant.fields.names() {
|
for field_name in variant.fields.names() {
|
||||||
body.push_parsed(format!(
|
body.push_parsed(format!(
|
||||||
"bincode::enc::Encode::encode({}, &mut encoder)?;",
|
"bincode::enc::Encode::encode({}, &mut encoder)?;",
|
||||||
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
|
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
|
||||||
));
|
))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
match_body.punct(',');
|
match_body.punct(',');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
fn_body.push_parsed("Ok(())");
|
fn_body.push_parsed("Ok(())").unwrap();
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,14 +93,15 @@ impl DeriveEnum {
|
||||||
// enum has a lifetime, implement BorrowDecode
|
// enum has a lifetime, implement BorrowDecode
|
||||||
|
|
||||||
generator.impl_for_with_de_lifetime("bincode::de::BorrowDecode<'__de>")
|
generator.impl_for_with_de_lifetime("bincode::de::BorrowDecode<'__de>")
|
||||||
|
.unwrap()
|
||||||
.generate_fn("borrow_decode")
|
.generate_fn("borrow_decode")
|
||||||
.with_generic("D", ["bincode::de::BorrowDecoder<'__de>"])
|
.with_generic("D", ["bincode::de::BorrowDecoder<'__de>"])
|
||||||
.with_arg("mut decoder", "D")
|
.with_arg("mut decoder", "D")
|
||||||
.with_return_type("Result<Self, bincode::error::DecodeError>")
|
.with_return_type("Result<Self, bincode::error::DecodeError>")
|
||||||
.body(|fn_builder| {
|
.body(|fn_builder| {
|
||||||
fn_builder
|
fn_builder
|
||||||
.push_parsed("let variant_index = <u32 as bincode::de::Decode>::decode(&mut decoder)?;");
|
.push_parsed("let variant_index = <u32 as bincode::de::Decode>::decode(&mut decoder)?;").unwrap();
|
||||||
fn_builder.push_parsed("match variant_index");
|
fn_builder.push_parsed("match variant_index").unwrap();
|
||||||
fn_builder.group(Delimiter::Brace, |variant_case| {
|
fn_builder.group(Delimiter::Brace, |variant_case| {
|
||||||
for (idx, variant) in variants.iter().enumerate() {
|
for (idx, variant) in variants.iter().enumerate() {
|
||||||
// idx => Ok(..)
|
// idx => Ok(..)
|
||||||
|
|
@ -120,7 +125,7 @@ impl DeriveEnum {
|
||||||
variant_body.ident(field.unwrap_ident().clone());
|
variant_body.ident(field.unwrap_ident().clone());
|
||||||
}
|
}
|
||||||
variant_body.punct(':');
|
variant_body.punct(':');
|
||||||
variant_body.push_parsed("bincode::de::BorrowDecode::borrow_decode(&mut decoder)?,");
|
variant_body.push_parsed("bincode::de::BorrowDecode::borrow_decode(&mut decoder)?,").unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -132,21 +137,21 @@ impl DeriveEnum {
|
||||||
"variant => return Err(bincode::error::DecodeError::UnexpectedVariant {{ min: 0, max: {}, found: variant, type_name: {:?} }})",
|
"variant => return Err(bincode::error::DecodeError::UnexpectedVariant {{ min: 0, max: {}, found: variant, type_name: {:?} }})",
|
||||||
variants.len() - 1,
|
variants.len() - 1,
|
||||||
enum_name.to_string()
|
enum_name.to_string()
|
||||||
));
|
)).unwrap();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}).unwrap();
|
||||||
} else {
|
} else {
|
||||||
// enum has no lifetimes, implement Decode
|
// enum has no lifetimes, implement Decode
|
||||||
generator.impl_for("bincode::de::Decode")
|
generator.impl_for("bincode::de::Decode")
|
||||||
|
.unwrap()
|
||||||
.generate_fn("decode")
|
.generate_fn("decode")
|
||||||
.with_generic("D", ["bincode::de::Decoder"])
|
.with_generic("D", ["bincode::de::Decoder"])
|
||||||
.with_arg("mut decoder", "D")
|
.with_arg("mut decoder", "D")
|
||||||
.with_return_type("Result<Self, bincode::error::DecodeError>")
|
.with_return_type("Result<Self, bincode::error::DecodeError>")
|
||||||
.body(|fn_builder| {
|
.body(|fn_builder| {
|
||||||
|
|
||||||
fn_builder
|
fn_builder
|
||||||
.push_parsed("let variant_index = <u32 as bincode::de::Decode>::decode(&mut decoder)?;");
|
.push_parsed("let variant_index = <u32 as bincode::de::Decode>::decode(&mut decoder)?;").unwrap();
|
||||||
fn_builder.push_parsed("match variant_index");
|
fn_builder.push_parsed("match variant_index").unwrap();
|
||||||
fn_builder.group(Delimiter::Brace, |variant_case| {
|
fn_builder.group(Delimiter::Brace, |variant_case| {
|
||||||
for (idx, variant) in variants.iter().enumerate() {
|
for (idx, variant) in variants.iter().enumerate() {
|
||||||
// idx => Ok(..)
|
// idx => Ok(..)
|
||||||
|
|
@ -170,7 +175,7 @@ impl DeriveEnum {
|
||||||
variant_body.ident(field.unwrap_ident().clone());
|
variant_body.ident(field.unwrap_ident().clone());
|
||||||
}
|
}
|
||||||
variant_body.punct(':');
|
variant_body.punct(':');
|
||||||
variant_body.push_parsed("bincode::de::Decode::decode(&mut decoder)?,");
|
variant_body.push_parsed("bincode::de::Decode::decode(&mut decoder)?,").unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -182,9 +187,9 @@ impl DeriveEnum {
|
||||||
"variant => return Err(bincode::error::DecodeError::UnexpectedVariant {{ min: 0, max: {}, found: variant, type_name: {:?} }})",
|
"variant => return Err(bincode::error::DecodeError::UnexpectedVariant {{ min: 0, max: {}, found: variant, type_name: {:?} }})",
|
||||||
variants.len() - 1,
|
variants.len() - 1,
|
||||||
enum_name.to_string()
|
enum_name.to_string()
|
||||||
));
|
)).unwrap();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,9 @@ impl DeriveStruct {
|
||||||
pub fn generate_encode(self, generator: &mut Generator) -> Result<()> {
|
pub fn generate_encode(self, generator: &mut Generator) -> Result<()> {
|
||||||
let DeriveStruct { fields } = self;
|
let DeriveStruct { fields } = self;
|
||||||
|
|
||||||
let mut impl_for = generator.impl_for("bincode::enc::Encode");
|
generator
|
||||||
impl_for
|
.impl_for("bincode::enc::Encode")
|
||||||
|
.unwrap()
|
||||||
.generate_fn("encode")
|
.generate_fn("encode")
|
||||||
.with_generic("E", ["bincode::enc::Encoder"])
|
.with_generic("E", ["bincode::enc::Encoder"])
|
||||||
.with_self_arg(crate::generate::FnSelfArg::RefSelf)
|
.with_self_arg(crate::generate::FnSelfArg::RefSelf)
|
||||||
|
|
@ -20,13 +21,16 @@ impl DeriveStruct {
|
||||||
.with_return_type("Result<(), bincode::error::EncodeError>")
|
.with_return_type("Result<(), bincode::error::EncodeError>")
|
||||||
.body(|fn_body| {
|
.body(|fn_body| {
|
||||||
for field in fields.names() {
|
for field in fields.names() {
|
||||||
fn_body.push_parsed(format!(
|
fn_body
|
||||||
|
.push_parsed(format!(
|
||||||
"bincode::enc::Encode::encode(&self.{}, &mut encoder)?;",
|
"bincode::enc::Encode::encode(&self.{}, &mut encoder)?;",
|
||||||
field.to_string()
|
field.to_string()
|
||||||
));
|
))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
fn_body.push_parsed("Ok(())");
|
fn_body.push_parsed("Ok(())").unwrap();
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -39,6 +43,7 @@ impl DeriveStruct {
|
||||||
|
|
||||||
generator
|
generator
|
||||||
.impl_for_with_de_lifetime("bincode::de::BorrowDecode<'__de>")
|
.impl_for_with_de_lifetime("bincode::de::BorrowDecode<'__de>")
|
||||||
|
.unwrap()
|
||||||
.generate_fn("borrow_decode")
|
.generate_fn("borrow_decode")
|
||||||
.with_generic("D", ["bincode::de::BorrowDecoder<'__de>"])
|
.with_generic("D", ["bincode::de::BorrowDecoder<'__de>"])
|
||||||
.with_arg("mut decoder", "D")
|
.with_arg("mut decoder", "D")
|
||||||
|
|
@ -50,21 +55,25 @@ impl DeriveStruct {
|
||||||
ok_group.ident_str("Self");
|
ok_group.ident_str("Self");
|
||||||
ok_group.group(Delimiter::Brace, |struct_body| {
|
ok_group.group(Delimiter::Brace, |struct_body| {
|
||||||
for field in fields.names() {
|
for field in fields.names() {
|
||||||
struct_body.push_parsed(format!(
|
struct_body
|
||||||
|
.push_parsed(format!(
|
||||||
"{}: bincode::de::BorrowDecode::borrow_decode(&mut decoder)?,",
|
"{}: bincode::de::BorrowDecode::borrow_decode(&mut decoder)?,",
|
||||||
field.to_string()
|
field.to_string()
|
||||||
));
|
))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
// struct has no lifetimes, implement Decode
|
// struct has no lifetimes, implement Decode
|
||||||
|
|
||||||
let mut impl_for = generator.impl_for("bincode::de::Decode");
|
generator
|
||||||
impl_for
|
.impl_for("bincode::de::Decode")
|
||||||
|
.unwrap()
|
||||||
.generate_fn("decode")
|
.generate_fn("decode")
|
||||||
.with_generic("D", ["bincode::de::Decoder"])
|
.with_generic("D", ["bincode::de::Decoder"])
|
||||||
.with_arg("mut decoder", "D")
|
.with_arg("mut decoder", "D")
|
||||||
|
|
@ -82,14 +91,17 @@ impl DeriveStruct {
|
||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
for field in fields.names() {
|
for field in fields.names() {
|
||||||
struct_body.push_parsed(format!(
|
struct_body
|
||||||
|
.push_parsed(format!(
|
||||||
"{}: bincode::de::Decode::decode(&mut decoder)?,",
|
"{}: bincode::de::Decode::decode(&mut decoder)?,",
|
||||||
field.to_string()
|
field.to_string()
|
||||||
));
|
))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use super::{ImplFor, StreamBuilder};
|
use super::{stream_builder::PushParseError, ImplFor, StreamBuilder};
|
||||||
use crate::prelude::Delimiter;
|
use crate::prelude::Delimiter;
|
||||||
|
|
||||||
/// A builder for functions.
|
/// A builder for functions.
|
||||||
pub struct FnBuilder<'a, 'b> {
|
pub struct FnBuilder<'a, 'b> {
|
||||||
generate: Option<&'b mut ImplFor<'a>>,
|
generate: &'b mut ImplFor<'a>,
|
||||||
name: String,
|
name: String,
|
||||||
|
|
||||||
lifetime_and_generics: Vec<(String, Vec<String>)>,
|
lifetime_and_generics: Vec<(String, Vec<String>)>,
|
||||||
|
|
@ -15,7 +15,7 @@ pub struct FnBuilder<'a, 'b> {
|
||||||
impl<'a, 'b> FnBuilder<'a, 'b> {
|
impl<'a, 'b> FnBuilder<'a, 'b> {
|
||||||
pub(super) fn new(generate: &'b mut ImplFor<'a>, name: impl Into<String>) -> Self {
|
pub(super) fn new(generate: &'b mut ImplFor<'a>, name: impl Into<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
generate: Some(generate),
|
generate,
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
lifetime_and_generics: Vec::new(),
|
lifetime_and_generics: Vec::new(),
|
||||||
self_arg: FnSelfArg::None,
|
self_arg: FnSelfArg::None,
|
||||||
|
|
@ -94,9 +94,9 @@ impl<'a, 'b> FnBuilder<'a, 'b> {
|
||||||
/// b.push_parsed("println!(\"hello world\");");
|
/// b.push_parsed("println!(\"hello world\");");
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
pub fn body(self, body_builder: impl FnOnce(&mut StreamBuilder)) {
|
pub fn body(self, body_builder: impl FnOnce(&mut StreamBuilder)) -> Result<(), PushParseError> {
|
||||||
let FnBuilder {
|
let FnBuilder {
|
||||||
mut generate,
|
generate,
|
||||||
name,
|
name,
|
||||||
lifetime_and_generics,
|
lifetime_and_generics,
|
||||||
self_arg,
|
self_arg,
|
||||||
|
|
@ -123,7 +123,7 @@ impl<'a, 'b> FnBuilder<'a, 'b> {
|
||||||
if !dependencies.is_empty() {
|
if !dependencies.is_empty() {
|
||||||
for (idx, dependency) in dependencies.into_iter().enumerate() {
|
for (idx, dependency) in dependencies.into_iter().enumerate() {
|
||||||
builder.punct(if idx == 0 { ':' } else { '+' });
|
builder.punct(if idx == 0 { ':' } else { '+' });
|
||||||
builder.push_parsed(&dependency);
|
builder.push_parsed(&dependency)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,22 +140,23 @@ impl<'a, 'b> FnBuilder<'a, 'b> {
|
||||||
if idx != 0 {
|
if idx != 0 {
|
||||||
arg_stream.punct(',');
|
arg_stream.punct(',');
|
||||||
}
|
}
|
||||||
arg_stream.push_parsed(&arg_name);
|
arg_stream.push_parsed(&arg_name)?;
|
||||||
arg_stream.punct(':');
|
arg_stream.punct(':');
|
||||||
arg_stream.push_parsed(&arg_ty);
|
arg_stream.push_parsed(&arg_ty)?;
|
||||||
}
|
}
|
||||||
});
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
// Return type: `-> ResultType`
|
// Return type: `-> ResultType`
|
||||||
if let Some(return_type) = return_type {
|
if let Some(return_type) = return_type {
|
||||||
builder.puncts("->");
|
builder.puncts("->");
|
||||||
builder.push_parsed(&return_type);
|
builder.push_parsed(&return_type)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let generator = generate.take().unwrap();
|
generate.group.append(builder);
|
||||||
|
generate.group.group(Delimiter::Brace, body_builder);
|
||||||
|
|
||||||
generator.group.append(builder);
|
Ok(())
|
||||||
generator.group.group(Delimiter::Brace, body_builder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use super::stream_builder::PushParseError;
|
||||||
use super::{ImplFor, StreamBuilder};
|
use super::{ImplFor, StreamBuilder};
|
||||||
use crate::parse::{GenericConstraints, Generics};
|
use crate::parse::{GenericConstraints, Generics};
|
||||||
use crate::prelude::{Ident, TokenStream};
|
use crate::prelude::{Ident, TokenStream};
|
||||||
|
|
@ -30,12 +31,15 @@ impl Generator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate an `for <trait_name> for <target_name>` implementation. See [ImplFor] for more information.
|
/// Generate an `for <trait_name> for <target_name>` implementation. See [ImplFor] for more information.
|
||||||
pub fn impl_for<'a>(&'a mut self, trait_name: &str) -> ImplFor<'a> {
|
pub fn impl_for<'a>(&'a mut self, trait_name: &str) -> Result<ImplFor<'a>, PushParseError> {
|
||||||
ImplFor::new(self, trait_name)
|
ImplFor::new(self, trait_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate an `for <'__de> <trait_name> for <target_name>` implementation. See [ImplFor] for more information.
|
/// Generate an `for <'__de> <trait_name> for <target_name>` implementation. See [ImplFor] for more information.
|
||||||
pub fn impl_for_with_de_lifetime<'a>(&'a mut self, trait_name: &str) -> ImplFor<'a> {
|
pub fn impl_for_with_de_lifetime<'a>(
|
||||||
|
&'a mut self,
|
||||||
|
trait_name: &str,
|
||||||
|
) -> Result<ImplFor<'a>, PushParseError> {
|
||||||
ImplFor::new_with_de_lifetime(self, trait_name)
|
ImplFor::new_with_de_lifetime(self, trait_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{FnBuilder, Generator, StreamBuilder};
|
use super::{stream_builder::PushParseError, FnBuilder, Generator, StreamBuilder};
|
||||||
use crate::prelude::Delimiter;
|
use crate::prelude::Delimiter;
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -8,14 +8,17 @@ pub struct ImplFor<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ImplFor<'a> {
|
impl<'a> ImplFor<'a> {
|
||||||
pub(super) fn new(generator: &'a mut Generator, trait_name: &str) -> Self {
|
pub(super) fn new(
|
||||||
|
generator: &'a mut Generator,
|
||||||
|
trait_name: &str,
|
||||||
|
) -> Result<Self, PushParseError> {
|
||||||
let mut builder = StreamBuilder::new();
|
let mut builder = StreamBuilder::new();
|
||||||
builder.ident_str("impl");
|
builder.ident_str("impl");
|
||||||
|
|
||||||
if let Some(generics) = &generator.generics {
|
if let Some(generics) = &generator.generics {
|
||||||
builder.append(generics.impl_generics());
|
builder.append(generics.impl_generics());
|
||||||
}
|
}
|
||||||
builder.push_parsed(trait_name);
|
builder.push_parsed(trait_name)?;
|
||||||
builder.ident_str("for");
|
builder.ident_str("for");
|
||||||
builder.ident(generator.name.clone());
|
builder.ident(generator.name.clone());
|
||||||
|
|
||||||
|
|
@ -28,10 +31,13 @@ impl<'a> ImplFor<'a> {
|
||||||
generator.stream.append(builder);
|
generator.stream.append(builder);
|
||||||
|
|
||||||
let group = StreamBuilder::new();
|
let group = StreamBuilder::new();
|
||||||
Self { generator, group }
|
Ok(Self { generator, group })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn new_with_de_lifetime(generator: &'a mut Generator, trait_name: &str) -> Self {
|
pub(super) fn new_with_de_lifetime(
|
||||||
|
generator: &'a mut Generator,
|
||||||
|
trait_name: &str,
|
||||||
|
) -> Result<Self, PushParseError> {
|
||||||
let mut builder = StreamBuilder::new();
|
let mut builder = StreamBuilder::new();
|
||||||
builder.ident_str("impl");
|
builder.ident_str("impl");
|
||||||
|
|
||||||
|
|
@ -43,7 +49,7 @@ impl<'a> ImplFor<'a> {
|
||||||
builder.punct('>');
|
builder.punct('>');
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.push_parsed(trait_name);
|
builder.push_parsed(trait_name)?;
|
||||||
builder.ident_str("for");
|
builder.ident_str("for");
|
||||||
builder.ident(generator.name.clone());
|
builder.ident(generator.name.clone());
|
||||||
if let Some(generics) = &generator.generics {
|
if let Some(generics) = &generator.generics {
|
||||||
|
|
@ -55,7 +61,7 @@ impl<'a> ImplFor<'a> {
|
||||||
generator.stream.append(builder);
|
generator.stream.append(builder);
|
||||||
|
|
||||||
let group = StreamBuilder::new();
|
let group = StreamBuilder::new();
|
||||||
Self { generator, group }
|
Ok(Self { generator, group })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a function to the trait implementation
|
/// Add a function to the trait implementation
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::prelude::{
|
use crate::prelude::{
|
||||||
Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
|
Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
|
||||||
};
|
};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
|
@ -36,15 +36,13 @@ impl StreamBuilder {
|
||||||
/// Attempt to parse the given string as valid Rust code, and append the parsed result to the internal stream.
|
/// Attempt to parse the given string as valid Rust code, and append the parsed result to the internal stream.
|
||||||
///
|
///
|
||||||
/// Currently panics if the string could not be parsed as valid Rust code.
|
/// Currently panics if the string could not be parsed as valid Rust code.
|
||||||
pub fn push_parsed(&mut self, item: impl AsRef<str>) {
|
pub fn push_parsed(&mut self, item: impl AsRef<str>) -> Result<(), PushParseError> {
|
||||||
self.stream
|
let tokens = TokenStream::from_str(item.as_ref()).map_err(|e| PushParseError {
|
||||||
.extend(TokenStream::from_str(item.as_ref()).unwrap_or_else(|e| {
|
error: e,
|
||||||
panic!(
|
code: item.as_ref().to_string(),
|
||||||
"Could not parse string as rust: {:?}\n{:?}",
|
})?;
|
||||||
item.as_ref(),
|
self.stream.extend(tokens);
|
||||||
e
|
Ok(())
|
||||||
)
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a single ident to the stream. An ident is any worse that a code file may contain, e.g. `fn`, `struct`, `where`, names of functions and structs, etc.
|
/// Push a single ident to the stream. An ident is any worse that a code file may contain, e.g. `fn`, `struct`, `where`, names of functions and structs, etc.
|
||||||
|
|
@ -63,11 +61,12 @@ impl StreamBuilder {
|
||||||
/// Add a group. A group is any block surrounded by `{ .. }`, `[ .. ]` or `( .. )`.
|
/// Add a group. A group is any block surrounded by `{ .. }`, `[ .. ]` or `( .. )`.
|
||||||
///
|
///
|
||||||
/// `delim` indicates which group it is. The `inner` callback is used to fill the contents of the group.
|
/// `delim` indicates which group it is. The `inner` callback is used to fill the contents of the group.
|
||||||
pub fn group(&mut self, delim: Delimiter, inner: impl FnOnce(&mut StreamBuilder)) {
|
pub fn group<T>(&mut self, delim: Delimiter, inner: impl FnOnce(&mut StreamBuilder) -> T) -> T {
|
||||||
let mut stream = StreamBuilder::new();
|
let mut stream = StreamBuilder::new();
|
||||||
inner(&mut stream);
|
let result = inner(&mut stream);
|
||||||
self.stream
|
self.stream
|
||||||
.extend([TokenTree::Group(Group::new(delim, stream.stream))]);
|
.extend([TokenTree::Group(Group::new(delim, stream.stream))]);
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a single punctuation to the stream. Puncts are single-character tokens like `.`, `<`, `#`, etc
|
/// Add a single punctuation to the stream. Puncts are single-character tokens like `.`, `<`, `#`, etc
|
||||||
|
|
@ -149,3 +148,9 @@ impl StreamBuilder {
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PushParseError {
|
||||||
|
pub error: LexError,
|
||||||
|
pub code: String,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue