Skip to content

Commit

Permalink
Sparser code generation
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Mar 29, 2024
1 parent b8b094d commit fe808cb
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 138 deletions.
8 changes: 4 additions & 4 deletions crates/musli-common/src/context/stack_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,17 +220,17 @@ where
}

#[inline]
fn enter_named_field<T>(&self, name: &'static str, _: T)
fn enter_named_field<T>(&self, name: &'static str, _: &T)
where
T: fmt::Display,
T: ?Sized + fmt::Display,
{
self.push_path(Step::Named(name));
}

#[inline]
fn enter_unnamed_field<T>(&self, index: u32, _: T)
fn enter_unnamed_field<T>(&self, index: u32, _: &T)
where
T: fmt::Display,
T: ?Sized + fmt::Display,
{
self.push_path(Step::Unnamed(index));
}
Expand Down
8 changes: 4 additions & 4 deletions crates/musli-common/src/context/system_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,17 @@ where
}

#[inline]
fn enter_named_field<T>(&self, name: &'static str, _: T)
fn enter_named_field<T>(&self, name: &'static str, _: &T)
where
T: fmt::Display,
T: ?Sized + fmt::Display,
{
self.push_path(Step::Named(name));
}

#[inline]
fn enter_unnamed_field<T>(&self, index: u32, _: T)
fn enter_unnamed_field<T>(&self, index: u32, _: &T)
where
T: fmt::Display,
T: ?Sized + fmt::Display,
{
self.push_path(Step::Unnamed(index));
}
Expand Down
134 changes: 71 additions & 63 deletions crates/musli-macros/src/de.rs

Large diffs are not rendered by default.

25 changes: 14 additions & 11 deletions crates/musli-macros/src/en.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ fn encode_struct(cx: &Ctxt<'_>, e: &Build<'_>, st: &Body<'_>) -> Result<TokenStr
encode = quote! {{
#enter
#(#decls)*
let #output_var = #encoder_t::encode_struct_fn(#encoder_var, #len, |#encoder_var| {
let #output_var = #encoder_t::encode_struct_fn(#encoder_var, #len, move |#encoder_var| {
#(#encoders)*
#result_ok(())
})?;
Expand All @@ -148,7 +148,7 @@ fn encode_struct(cx: &Ctxt<'_>, e: &Build<'_>, st: &Body<'_>) -> Result<TokenStr

encode = quote! {{
#enter
let #output_var = #encoder_t::encode_pack_fn(#encoder_var, |#pack_var| {
let #output_var = #encoder_t::encode_pack_fn(#encoder_var, move |#pack_var| {
#(#decls)*
#(#encoders)*
#result_ok(())
Expand Down Expand Up @@ -236,7 +236,7 @@ fn insert_fields<'st>(
encode = quote! {
#enter

#struct_encoder_t::encode_struct_field_fn(#encoder_var, |#pair_encoder_var| {
#struct_encoder_t::encode_struct_field_fn(#encoder_var, move |#pair_encoder_var| {
let #field_encoder_var = #struct_field_encoder_t::encode_field_name(#pair_encoder_var)?;
#encode_t_encode(&#tag, #ctx_var, #field_encoder_var)?;
let #value_encoder_var = #struct_field_encoder_t::encode_field_value(#pair_encoder_var)?;
Expand Down Expand Up @@ -284,7 +284,10 @@ fn encode_enum(cx: &Ctxt<'_>, e: &Build<'_>, en: &Enum<'_>) -> Result<TokenStrea
let Ctxt { ctx_var, .. } = *cx;

let Tokens {
context_t, result_ok, result_err, ..
context_t,
result_ok,
result_err,
..
} = e.tokens;

let type_name = en.name;
Expand Down Expand Up @@ -360,7 +363,7 @@ fn encode_variant(
let decls = tests.iter().map(|t| &t.decl);

encode = quote! {{
#encoder_t::encode_pack_fn(#encoder_var, |#pack_var| {
#encoder_t::encode_pack_fn(#encoder_var, move |#pack_var| {
#(#decls)*
#(#encoders)*
#result_ok(())
Expand All @@ -372,7 +375,7 @@ fn encode_variant(
let len = length_test(v.st.fields.len(), &tests);

encode = quote! {{
#encoder_t::encode_struct_fn(#encoder_var, #len, |#encoder_var| {
#encoder_t::encode_struct_fn(#encoder_var, #len, move |#encoder_var| {
#(#decls)*
#(#encoders)*
#result_ok(())
Expand All @@ -388,7 +391,7 @@ fn encode_variant(
let tag_encoder = b.cx.ident("tag_encoder");

encode = quote! {{
#encoder_t::encode_variant_fn(#encoder_var, |#variant_encoder| {
#encoder_t::encode_variant_fn(#encoder_var, move |#variant_encoder| {
let #tag_encoder = #variant_encoder_t::encode_tag(#variant_encoder)?;
#encode_t_encode(&#tag, #ctx_var, #tag_encoder)?;

Expand All @@ -409,7 +412,7 @@ fn encode_variant(
let decls = tests.iter().map(|t| &t.decl);

encode = quote! {{
#encoder_t::encode_struct_fn(#encoder_var, 0, |#encoder_var| {
#encoder_t::encode_struct_fn(#encoder_var, 0, move |#encoder_var| {
#struct_encoder_t::insert_struct_field(#encoder_var, #field_tag, #tag)?;
#(#decls)*
#(#encoders)*
Expand All @@ -436,16 +439,16 @@ fn encode_variant(
let content_tag = b.cx.ident("content_tag");

encode = quote! {{
#encoder_t::encode_struct_fn(#encoder_var, 2, |#struct_encoder| {
#encoder_t::encode_struct_fn(#encoder_var, 2, move |#struct_encoder| {
#struct_encoder_t::insert_struct_field(#struct_encoder, &#field_tag, #tag)?;

#struct_encoder_t::encode_struct_field_fn(#struct_encoder, |#pair| {
#struct_encoder_t::encode_struct_field_fn(#struct_encoder, move |#pair| {
let #content_tag = #struct_field_encoder_t::encode_field_name(#pair)?;
#encode_t_encode(&#content, #ctx_var, #content_tag)?;

let #content_struct = #struct_field_encoder_t::encode_field_value(#pair)?;

#encoder_t::encode_struct_fn(#content_struct, #len, |#encoder_var| {
#encoder_t::encode_struct_fn(#content_struct, #len, move |#encoder_var| {
#(#decls)*
#(#encoders)*
#result_ok(())
Expand Down
6 changes: 4 additions & 2 deletions crates/musli-macros/src/internals/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,10 @@ fn setup_field<'a>(
};

let var = match &member {
syn::Member::Named(ident) => e.cx.ident_with_span(&ident.to_string(), ident.span(), "f_"),
syn::Member::Unnamed(index) => e.cx.ident_with_span(&index.index.to_string(), index.span, "f_"),
syn::Member::Named(ident) => e.cx.ident_with_span(&ident.to_string(), ident.span(), "_f"),
syn::Member::Unnamed(index) => {
e.cx.ident_with_span(&index.index.to_string(), index.span, "_f")
}
};

Ok(Field {
Expand Down
57 changes: 43 additions & 14 deletions crates/musli-macros/src/internals/ctxt.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
use std::cell::RefCell;
use std::collections::HashSet;
use std::fmt::{self, Write};
#[cfg(not(feature = "verbose"))]
use std::collections::HashMap;
use std::collections::HashSet;
use std::fmt::{self, Write};

use proc_macro2::Span;

struct Inner {
b1: String,
modes: HashSet<syn::Path>,
errors: Vec<syn::Error>,
#[cfg(not(feature = "verbose"))]
names: HashMap<String, usize>,
#[cfg(not(feature = "verbose"))]
types: usize,
}

pub(crate) struct Ctxt {
Expand All @@ -25,7 +28,10 @@ impl Ctxt {
b1: String::new(),
modes: HashSet::new(),
errors: Vec::new(),
#[cfg(not(feature = "verbose"))]
names: HashMap::new(),
#[cfg(not(feature = "verbose"))]
types: 0,
}),
}
}
Expand Down Expand Up @@ -67,8 +73,12 @@ impl Ctxt {
}

pub(crate) fn reset(&self) {
let mut inner = self.inner.borrow_mut();
inner.names.clear();
#[cfg(not(feature = "verbose"))]
{
let mut inner = self.inner.borrow_mut();
inner.names.clear();
inner.types = 0;
}
}

/// Build an identifier with the given name, escaped so it's harder to conflict with.
Expand All @@ -80,16 +90,16 @@ impl Ctxt {
pub(crate) fn ident_with_span(&self, name: &str, span: Span, extra: &str) -> syn::Ident {
let mut inner = self.inner.borrow_mut();

let index = if let Some(index) = inner.names.get(name) {
*index
} else {
let index = inner.names.len();
inner.names.insert(name.to_owned(), index);
index
};

#[cfg(not(feature = "verbose"))]
{
let index = if let Some(index) = inner.names.get(name) {
*index
} else {
let index = inner.names.len();
inner.names.insert(name.to_owned(), index);
index
};

_ = write!(inner.b1, "_{index}{extra}");
}

Expand All @@ -105,9 +115,28 @@ impl Ctxt {
}

/// Build a type identifier with a span.
pub(crate) fn type_with_span(&self, name: &str, span: Span) -> syn::Ident {
pub(crate) fn type_with_span<N>(
&self,
#[cfg_attr(not(feature = "verbose"), allow(unused))] name: N,
span: Span,
) -> syn::Ident
where
N: fmt::Display,
{
let mut inner = self.inner.borrow_mut();
_ = write!(inner.b1, "__{name}");

#[cfg(not(feature = "verbose"))]
{
let index = inner.types;
inner.types += 1;
_ = write!(inner.b1, "T{index}");
}

#[cfg(feature = "verbose")]
{
_ = write!(inner.b1, "{name}");
}

let ident = syn::Ident::new(&inner.b1, span);
inner.b1.clear();
ident
Expand Down
4 changes: 3 additions & 1 deletion crates/musli-macros/src/internals/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub(crate) struct Tokens {
pub(crate) result: syn::Path,
pub(crate) result_ok: syn::Path,
pub(crate) result_err: syn::Path,
pub(crate) skip_field: syn::Path,
pub(crate) skip: syn::Path,
pub(crate) str_ty: syn::Path,
pub(crate) struct_decoder_t: syn::Path,
Expand Down Expand Up @@ -61,7 +62,8 @@ impl Tokens {
result: path(span, prefix, ["__priv", "Result"]),
result_ok: path(span, prefix, ["__priv", "Ok"]),
result_err: path(span, prefix, ["__priv", "Err"]),
skip: path(span, prefix, ["de", "Skip"]),
skip_field: path(span, prefix, ["__priv", "skip_field"]),
skip: path(span, prefix, ["__priv", "skip"]),
pack_encoder_t: path(span, prefix, ["en", "PackEncoder"]),
trace_decode_t: path(span, prefix, ["de", "TraceDecode"]),
trace_encode_t: path(span, prefix, ["en", "TraceEncode"]),
Expand Down
38 changes: 22 additions & 16 deletions crates/musli/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Things related to working with contexts.

use core::fmt;
use core::str;

use crate::de::DecodeBytes;
use crate::{Buf, Decode, Decoder};
Expand Down Expand Up @@ -139,18 +140,18 @@ pub trait Context {

/// Report that an invalid variant tag was encountered.
#[inline(always)]
fn invalid_variant_tag<T>(&self, _: &'static str, tag: T) -> Self::Error
fn invalid_variant_tag<T>(&self, _: &'static str, tag: &T) -> Self::Error
where
T: fmt::Debug,
T: ?Sized + fmt::Debug,
{
self.message(format_args!("Invalid variant tag: {tag:?}"))
}

/// The value for the given tag could not be collected.
#[inline(always)]
fn expected_tag<T>(&self, _: &'static str, tag: T) -> Self::Error
fn expected_tag<T>(&self, _: &'static str, tag: &T) -> Self::Error
where
T: fmt::Debug,
T: ?Sized + fmt::Debug,
{
self.message(format_args!("Expected tag: {tag:?}"))
}
Expand All @@ -163,9 +164,9 @@ pub trait Context {

/// Encountered an unsupported field tag.
#[inline(always)]
fn invalid_field_tag<T>(&self, _: &'static str, tag: T) -> Self::Error
fn invalid_field_tag<T>(&self, _: &'static str, tag: &T) -> Self::Error
where
T: fmt::Debug,
T: ?Sized + fmt::Debug,
{
self.message(format_args!("Invalid field tag `{tag:?}`"))
}
Expand All @@ -176,7 +177,7 @@ pub trait Context {
// SAFETY: Getting the slice does not overlap any interleaving operations.
let bytes = field.as_slice();

if let Ok(string) = core::str::from_utf8(bytes) {
if let Ok(string) = str::from_utf8(bytes) {
self.message(format_args!("Invalid field tag: {string}"))
} else {
self.message(format_args!("Invalid field tag"))
Expand All @@ -186,9 +187,9 @@ pub trait Context {
/// Missing variant field required to decode.
#[allow(unused_variables)]
#[inline(always)]
fn missing_variant_field<T>(&self, name: &'static str, tag: T) -> Self::Error
fn missing_variant_field<T>(&self, name: &'static str, tag: &T) -> Self::Error
where
T: fmt::Debug,
T: ?Sized + fmt::Debug,
{
self.message(format_args!("Missing variant field: {tag:?}"))
}
Expand All @@ -203,10 +204,15 @@ pub trait Context {
/// Encountered an unsupported variant field.
#[allow(unused_variables)]
#[inline(always)]
fn invalid_variant_field_tag<V, T>(&self, name: &'static str, variant: V, tag: T) -> Self::Error
fn invalid_variant_field_tag<V, T>(
&self,
name: &'static str,
variant: &V,
tag: &T,
) -> Self::Error
where
V: fmt::Debug,
T: fmt::Debug,
V: ?Sized + fmt::Debug,
T: ?Sized + fmt::Debug,
{
self.message(format_args!(
"Invalid variant field tag `{tag:?}` for variant `{variant:?}`",
Expand Down Expand Up @@ -273,9 +279,9 @@ pub trait Context {
/// [`leave_field`]: Context::leave_field
#[allow(unused_variables)]
#[inline(always)]
fn enter_named_field<T>(&self, name: &'static str, tag: T)
fn enter_named_field<T>(&self, name: &'static str, tag: &T)
where
T: fmt::Display,
T: ?Sized + fmt::Display,
{
}

Expand All @@ -299,9 +305,9 @@ pub trait Context {
/// [`leave_field`]: Context::leave_field
#[allow(unused_variables)]
#[inline(always)]
fn enter_unnamed_field<T>(&self, index: u32, tag: T)
fn enter_unnamed_field<T>(&self, index: u32, tag: &T)
where
T: fmt::Display,
T: ?Sized + fmt::Display,
{
}

Expand Down
Loading

0 comments on commit fe808cb

Please sign in to comment.