Skip to content

Commit

Permalink
Reduce work done by macros
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Dec 31, 2024
1 parent cf8e3d8 commit 3c1fc3a
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 304 deletions.
18 changes: 11 additions & 7 deletions crates/musli-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,23 @@ pub use musli_macros::visitor;
/// Using these directly is not supported.
#[doc(hidden)]
pub mod __priv {
use crate::context::Context;
use crate::de::{Decoder, EntryDecoder};
pub use crate::context::Context;
pub use crate::de::{
AsDecoder, Decode, DecodeBytes, DecodePacked, DecodeTrace, Decoder, EntryDecoder,
MapDecoder, SequenceDecoder, VariantDecoder,
};
pub use crate::en::{
Encode, EncodeBytes, EncodePacked, EncodeTrace, Encoder, EntryEncoder, MapEncoder,
SequenceEncoder, VariantEncoder,
};
pub use crate::hint::MapHint;
pub use crate::never::Never;

pub use ::core::fmt;
pub use ::core::mem::{offset_of, size_of};
pub use ::core::option::Option;
pub use ::core::result::Result;

pub use crate::never::Never;

#[inline(always)]
pub fn default<T>() -> T
where
Expand All @@ -230,7 +237,4 @@ pub mod __priv {
{
skip(decoder.decode_value()?)
}

pub use Option::{None, Some};
pub use Result::{Err, Ok};
}
149 changes: 58 additions & 91 deletions crates/musli-macros/src/de.rs

Large diffs are not rendered by default.

41 changes: 19 additions & 22 deletions crates/musli-macros/src/en.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub(crate) fn expand_insert_entry(e: Build<'_>) -> Result<TokenStream> {

let body = match &e.data {
BuildData::Struct(st) => {
packed = crate::packed::packed(&e, st, &e.tokens.encode_t, "ENCODE_PACKED");
packed = crate::packed::packed(&e, st, e.tokens.encode_t, "ENCODE_PACKED");
encode_map(&cx, &e, st)?
}
BuildData::Enum(en) => {
Expand Down Expand Up @@ -73,7 +73,7 @@ pub(crate) fn expand_insert_entry(e: Build<'_>) -> Result<TokenStream> {
attributes.push(syn::parse_quote!(#[allow(clippy::just_underscores_and_digits)]));
}

let mode_ident = e.expansion.mode_path(e.tokens).as_path();
let mode_ident = e.expansion.mode_path(&e.tokens);

Ok(quote! {
const _: () = {
Expand Down Expand Up @@ -116,7 +116,7 @@ fn encode_map(cx: &Ctxt<'_>, b: &Build<'_>, st: &Body<'_>) -> Result<TokenStream
let Tokens {
context_t,
encoder_t,
result_ok,
result,
..
} = b.tokens;

Expand Down Expand Up @@ -161,7 +161,7 @@ fn encode_map(cx: &Ctxt<'_>, b: &Build<'_>, st: &Body<'_>) -> Result<TokenStream

let #output_var = #encoder_t::encode_map_fn(#encoder_var, &#hint, move |#encoder_var| {
#(#encoders)*
#result_ok(())
#result::Ok(())
})?;
#leave
#output_var
Expand All @@ -175,15 +175,15 @@ fn encode_map(cx: &Ctxt<'_>, b: &Build<'_>, st: &Body<'_>) -> Result<TokenStream
let #output_var = #encoder_t::encode_pack_fn(#encoder_var, move |#pack_var| {
#(#decls)*
#(#encoders)*
#result_ok(())
#result::Ok(())
})?;
#leave
#output_var
}};
}
}

Ok(quote!(#result_ok(#encode)))
Ok(quote!(#result::Ok(#encode)))
}

struct FieldTest<'st> {
Expand All @@ -206,7 +206,7 @@ fn insert_fields<'st>(
let Tokens {
context_t,
sequence_encoder_t,
result_ok,
result,

map_encoder_t,
map_entry_encoder_t,
Expand Down Expand Up @@ -271,7 +271,7 @@ fn insert_fields<'st>(
#encode_t_encode(#field_name_expr, #field_encoder_var)?;
let #value_encoder_var = #map_entry_encoder_t::encode_value(#pair_encoder_var)?;
#encode_path(#access, #value_encoder_var)?;
#result_ok(())
#result::Ok(())
})?;

#leave
Expand Down Expand Up @@ -321,10 +321,7 @@ fn encode_enum(cx: &Ctxt<'_>, b: &Build<'_>, en: &Enum<'_>) -> Result<TokenStrea
let Ctxt { ctx_var, .. } = *cx;

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

let type_name = en.name;
Expand All @@ -346,9 +343,9 @@ fn encode_enum(cx: &Ctxt<'_>, b: &Build<'_>, en: &Enum<'_>) -> Result<TokenStrea

// Special case: uninhabitable types.
Ok(if variants.is_empty() {
quote!(#result_err(#context_t::uninhabitable(#ctx_var, #type_name)))
quote!(#result::Err(#context_t::uninhabitable(#ctx_var, #type_name)))
} else {
quote!(#result_ok(match self { #(#variants),* }))
quote!(#result::Ok(match self { #(#variants),* }))
})
}

Expand All @@ -372,7 +369,7 @@ fn encode_variant(
let Tokens {
context_t,
encoder_t,
result_ok,
result,
map_encoder_t,
map_entry_encoder_t,
variant_encoder_t,
Expand Down Expand Up @@ -419,7 +416,7 @@ fn encode_variant(
#encoder_t::encode_pack_fn(#encoder_var, move |#pack_var| {
#(#decls)*
#(#encoders)*
#result_ok(())
#result::Ok(())
})?
}};
}
Expand All @@ -434,7 +431,7 @@ fn encode_variant(
#encoder_t::encode_map_fn(#encoder_var, &#hint, move |#encoder_var| {
#(#decls)*
#(#encoders)*
#result_ok(())
#result::Ok(())
})?
}};
}
Expand All @@ -454,7 +451,7 @@ fn encode_variant(

let #encoder_var = #variant_encoder_t::encode_data(#variant_encoder)?;
#encode;
#result_ok(())
#result::Ok(())
})?
}};
}
Expand Down Expand Up @@ -486,7 +483,7 @@ fn encode_variant(
#map_encoder_t::insert_entry(#encoder_var, #tag_static, #name_static)?;
#(#decls)*
#(#encoders)*
#result_ok(())
#result::Ok(())
})?
}};
}
Expand Down Expand Up @@ -534,13 +531,13 @@ fn encode_variant(
#encoder_t::encode_map_fn(#content_struct, &#inner_hint, move |#encoder_var| {
#(#decls)*
#(#encoders)*
#result_ok(())
#result::Ok(())
})?;

#result_ok(())
#result::Ok(())
})?;

#result_ok(())
#result::Ok(())
})?
}};
}
Expand Down
18 changes: 11 additions & 7 deletions crates/musli-macros/src/expander.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::borrow::Cow;
use std::collections::BTreeMap;

use proc_macro2::{Span, TokenStream};
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;

use crate::de;
use crate::internals::attr::{self, ModeIdent, ModeKind, TypeAttr};
use crate::internals::build::Build;
use crate::internals::name::NameAll;
Expand Down Expand Up @@ -41,19 +41,19 @@ impl NameType<'_> {
}
}

pub(crate) fn ty(&self) -> syn::Type {
pub(crate) fn ty(&self) -> Cow<'_, syn::Type> {
match self.method {
NameMethod::Unsized(..) => {
let ty = &self.ty;
syn::parse_quote!(&#ty)
Cow::Owned(syn::parse_quote!(&#ty))
}
NameMethod::Value => self.ty.clone(),
NameMethod::Value => Cow::Borrowed(&self.ty),
}
}

pub(crate) fn name_format(&self, value: &syn::Ident) -> syn::Expr {
match self.format_with {
Some((_, path)) => de::build_call(path, [syn::parse_quote!(&#value)]),
Some((_, path)) => syn::parse_quote!(#path(&#value)),
None => syn::parse_quote!(&#value),
}
}
Expand Down Expand Up @@ -143,7 +143,7 @@ pub(crate) struct Expander<'a> {
pub(crate) cx: Ctxt,
pub(crate) type_attr: TypeAttr,
pub(crate) data: Data<'a>,
pub(crate) tokens: Tokens,
pub(crate) prefix: syn::Path,
pub(crate) default: Vec<ModeIdent>,
}

Expand Down Expand Up @@ -223,11 +223,15 @@ impl<'a> Expander<'a> {
cx,
type_attr,
data,
tokens: Tokens::new(input.ident.span(), prefix),
prefix,
default,
}
}

pub(crate) fn tokens(&self) -> Tokens<'_> {
Tokens::new(&self.prefix)
}

/// Coerce into errors.
pub(crate) fn into_errors(self) -> Vec<syn::Error> {
self.cx.into_errors()
Expand Down
37 changes: 31 additions & 6 deletions crates/musli-macros/src/internals/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::mem;

use proc_macro2::Span;
use quote::ToTokens;
use syn::meta::ParseNestedMeta;
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
Expand All @@ -13,6 +14,7 @@ use crate::internals::ATTR;
use crate::internals::{Ctxt, Mode};

use super::build;
use super::mode::Method;

#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub(crate) enum ModeKind {
Expand Down Expand Up @@ -670,28 +672,51 @@ layer! {

impl Field {
/// Expand encode of the given field.
pub(crate) fn encode_path_expanded(&self, mode: Mode<'_>, span: Span) -> (Span, syn::Path) {
pub(crate) fn encode_path_expanded<'a>(
&self,
mode: Mode<'a>,
span: Span,
) -> (Span, MethodOrPath<'a>) {
let encode_path = self.encode_path(mode);

if let Some((span, encode_path)) = encode_path {
(*span, encode_path.clone())
(*span, MethodOrPath::Path(encode_path.clone()))
} else {
let field_encoding = self.encoding(mode).map(|&(_, e)| e).unwrap_or_default();
let encode_path = mode.encode_t_encode(field_encoding);
(span, encode_path)
(span, MethodOrPath::Method(encode_path))
}
}

/// Expand decode of the given field.
pub(crate) fn decode_path_expanded(&self, mode: Mode<'_>, span: Span) -> (Span, syn::Path) {
pub(crate) fn decode_path_expanded<'a>(
&self,
mode: Mode<'a>,
span: Span,
) -> (Span, MethodOrPath<'a>) {
let decode_path = self.decode_path(mode);

if let Some((span, decode_path)) = decode_path {
(*span, decode_path.clone())
(*span, MethodOrPath::Path(decode_path.clone()))
} else {
let field_encoding = self.encoding(mode).map(|&(_, e)| e).unwrap_or_default();
let decode_path = mode.decode_t_decode(field_encoding);
(span, decode_path)
(span, MethodOrPath::Method(decode_path))
}
}
}

pub(crate) enum MethodOrPath<'a> {
Method(Method<'a>),
Path(syn::Path),
}

impl ToTokens for MethodOrPath<'_> {
#[inline]
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
match self {
MethodOrPath::Method(method) => method.to_tokens(tokens),
MethodOrPath::Path(path) => path.to_tokens(tokens),
}
}
}
Expand Down
Loading

0 comments on commit 3c1fc3a

Please sign in to comment.