Fix crate derivation at the cost of having to put all of rusty value into scope

main
trivernis 2 years ago
parent e3f41d7e0d
commit 136ef062c4
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -3,7 +3,7 @@ members = [".", "derive"]
[package] [package]
name = "rusty-value" name = "rusty-value"
version = "0.5.0" version = "0.5.1"
edition = "2021" edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
repository = "https://github.com/Trivernis/rusty-value" repository = "https://github.com/Trivernis/rusty-value"
@ -16,7 +16,7 @@ serde_json = { version = "1.0.85", default-features = false, optional = true, fe
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies.rusty-value-derive] [dependencies.rusty-value-derive]
version = "0.1.0" version = "0.1.1"
path = "./derive" path = "./derive"
optional = true optional = true

@ -1,6 +1,6 @@
[package] [package]
name = "rusty-value-derive" name = "rusty-value-derive"
version = "0.1.0" version = "0.1.1"
edition = "2021" edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
repository = "https://github.com/Trivernis/rusty-value" repository = "https://github.com/Trivernis/rusty-value"
@ -13,7 +13,6 @@ proc-macro = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
proc-macro-crate = "1.2.1"
proc-macro2 = "1.0.46" proc-macro2 = "1.0.46"
quote = "1.0.21" quote = "1.0.21"

@ -24,7 +24,6 @@ fn derive_struct(input: &DeriveInput, struct_data: &DataStruct) -> TokenStream {
let name = ident.to_string(); let name = ident.to_string();
let (impl_generics, ty_generics, _) = input.generics.split_for_impl(); let (impl_generics, ty_generics, _) = input.generics.split_for_impl();
let where_clause = add_rusty_bound(&input.generics); let where_clause = add_rusty_bound(&input.generics);
let rusty_value = get_rusty_value_crate();
match &struct_data.fields { match &struct_data.fields {
syn::Fields::Named(FieldsNamed { named, .. }) => { syn::Fields::Named(FieldsNamed { named, .. }) => {
@ -36,9 +35,8 @@ fn derive_struct(input: &DeriveInput, struct_data: &DataStruct) -> TokenStream {
let field_count = named.len(); let field_count = named.len();
TokenStream::from(quote! { TokenStream::from(quote! {
impl #impl_generics #rusty_value::RustyValue for #ident #ty_generics #where_clause { impl #impl_generics RustyValue for #ident #ty_generics #where_clause {
fn into_rusty_value(self) -> #rusty_value::Value { fn into_rusty_value(self) -> Value {
use #rusty_value::*;
let mut values = std::collections::HashMap::with_capacity(#field_count); let mut values = std::collections::HashMap::with_capacity(#field_count);
#( #(
@ -62,9 +60,8 @@ fn derive_struct(input: &DeriveInput, struct_data: &DataStruct) -> TokenStream {
let field_count = unnamed.len(); let field_count = unnamed.len();
TokenStream::from(quote! { TokenStream::from(quote! {
impl #impl_generics #rusty_value::RustyValue for #ident #ty_generics #where_clause { impl #impl_generics RustyValue for #ident #ty_generics #where_clause {
fn into_rusty_value(self) -> #rusty_value::Value { fn into_rusty_value(self) -> Value {
use #rusty_value::*;
let mut values = Vec::with_capacity(#field_count); let mut values = Vec::with_capacity(#field_count);
#( #(
@ -80,9 +77,8 @@ fn derive_struct(input: &DeriveInput, struct_data: &DataStruct) -> TokenStream {
}) })
} }
syn::Fields::Unit => TokenStream::from(quote! { syn::Fields::Unit => TokenStream::from(quote! {
impl #impl_generics #rusty_value::RustyValue for #ident #ty_generics #where_clause { impl #impl_generics RustyValue for #ident #ty_generics #where_clause {
fn into_rusty_value(self) -> #rusty_value::Value { fn into_rusty_value(self) -> Value {
use #rusty_value::*;
Value::Struct(Struct{ Value::Struct(Struct{
name: #name.to_string(), name: #name.to_string(),
fields: Fields::Unit, fields: Fields::Unit,
@ -102,15 +98,14 @@ fn derive_enum(input: &DeriveInput, enum_data: &DataEnum) -> TokenStream {
.iter() .iter()
.map(|v| create_enum_value_match(ident, v)) .map(|v| create_enum_value_match(ident, v))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let rusty_value = get_rusty_value_crate();
TokenStream::from(quote! { TokenStream::from(quote! {
impl #impl_generics #rusty_value::RustyValue for #ident #ty_generics #where_clause { impl #impl_generics RustyValue for #ident #ty_generics #where_clause {
fn into_rusty_value(self) -> #rusty_value::Value { fn into_rusty_value(self) -> Value {
let enum_val = match self { let enum_val = match self {
#( #variant_matchers )* #( #variant_matchers )*
}; };
#rusty_value::Value::Enum(enum_val) Value::Enum(enum_val)
} }
} }
}) })
@ -120,7 +115,6 @@ fn create_enum_value_match(ident: &syn::Ident, variant: &Variant) -> proc_macro2
let enum_name = ident.to_string(); let enum_name = ident.to_string();
let variant_ident = &variant.ident; let variant_ident = &variant.ident;
let variant_name = variant_ident.to_string(); let variant_name = variant_ident.to_string();
let rusty_value = get_rusty_value_crate();
match &variant.fields { match &variant.fields {
syn::Fields::Named(FieldsNamed { named, .. }) => { syn::Fields::Named(FieldsNamed { named, .. }) => {
@ -133,8 +127,6 @@ fn create_enum_value_match(ident: &syn::Ident, variant: &Variant) -> proc_macro2
quote! { quote! {
#ident::#variant_ident { #( #field_idents, )* } => { #ident::#variant_ident { #( #field_idents, )* } => {
use #rusty_value::*;
let mut fields = std::collections::HashMap::with_capacity(#field_count); let mut fields = std::collections::HashMap::with_capacity(#field_count);
#( #(
fields.insert(#field_names.to_string(), #field_idents.into_rusty_value()); fields.insert(#field_names.to_string(), #field_idents.into_rusty_value());
@ -157,8 +149,6 @@ fn create_enum_value_match(ident: &syn::Ident, variant: &Variant) -> proc_macro2
quote! { quote! {
#ident::#variant_ident ( #( #field_names, )* ) => { #ident::#variant_ident ( #( #field_names, )* ) => {
use #rusty_value::*;
let mut fields = Vec::with_capacity(#field_count); let mut fields = Vec::with_capacity(#field_count);
#( #(
fields.push(#field_names.into_rusty_value()); fields.push(#field_names.into_rusty_value());
@ -173,8 +163,6 @@ fn create_enum_value_match(ident: &syn::Ident, variant: &Variant) -> proc_macro2
} }
syn::Fields::Unit => quote! { syn::Fields::Unit => quote! {
#ident::#variant_ident => { #ident::#variant_ident => {
use #rusty_value::*;
Enum { Enum {
name: #enum_name.to_string(), name: #enum_name.to_string(),
variant: #variant_name.to_string(), variant: #variant_name.to_string(),
@ -200,12 +188,3 @@ fn add_rusty_bound(generics: &Generics) -> WhereClause {
.extend(new_predicates); .extend(new_predicates);
generics.where_clause.unwrap() generics.where_clause.unwrap()
} }
fn get_rusty_value_crate() -> proc_macro2::TokenStream {
use proc_macro_crate::{crate_name, FoundCrate};
match crate_name("rusty_value") {
Ok(FoundCrate::Itself) => quote!(rusty_value),
Err(_) => quote!(crate),
Ok(FoundCrate::Name(name)) => quote!(#name),
}
}

@ -1,8 +1,7 @@
use serde_json::{Number, Value}; use crate::*;
use serde_json::Number;
use std::string::ToString; use std::string::ToString;
use crate::{Enum, HashableValue, Primitive, RustyValue, Struct};
/// Options for how to represent certain rust types /// Options for how to represent certain rust types
/// as JSON /// as JSON
#[derive(Clone, Debug, RustyValue, Default)] #[derive(Clone, Debug, RustyValue, Default)]
@ -32,96 +31,96 @@ impl Default for EnumRepr {
/// Trait to convert a value into a json value /// Trait to convert a value into a json value
pub trait IntoJson { pub trait IntoJson {
/// Converts the value into a json value with default options /// Converts the value into a json value with default options
fn into_json(self) -> Value; fn into_json(self) -> serde_json::Value;
/// Converts the value into a json value with the given options /// Converts the value into a json value with the given options
fn into_json_with_options(self, options: &IntoJsonOptions) -> Value; fn into_json_with_options(self, options: &IntoJsonOptions) -> serde_json::Value;
} }
trait RustyIntoJson { trait RustyIntoJson {
/// Converts the value into a json value with default options /// Converts the value into a json value with default options
fn into_json(self) -> Value; fn into_json(self) -> serde_json::Value;
/// Converts the value into a json value with the given options /// Converts the value into a json value with the given options
fn into_json_with_options(self, options: &IntoJsonOptions) -> Value; fn into_json_with_options(self, options: &IntoJsonOptions) -> serde_json::Value;
} }
impl RustyIntoJson for crate::Value { impl RustyIntoJson for crate::Value {
#[inline] #[inline]
fn into_json(self) -> Value { fn into_json(self) -> serde_json::Value {
self.into_json_with_options(&IntoJsonOptions::default()) self.into_json_with_options(&IntoJsonOptions::default())
} }
fn into_json_with_options(self, opt: &IntoJsonOptions) -> Value { fn into_json_with_options(self, opt: &IntoJsonOptions) -> serde_json::Value {
match self { match self {
crate::Value::Primitive(p) => p.into_json_with_options(opt), crate::Value::Primitive(p) => p.into_json_with_options(opt),
crate::Value::Struct(s) => s.into_json_with_options(opt), crate::Value::Struct(s) => s.into_json_with_options(opt),
crate::Value::Enum(e) => e.into_json_with_options(opt), crate::Value::Enum(e) => e.into_json_with_options(opt),
crate::Value::Map(m) => Value::Object( crate::Value::Map(m) => serde_json::Value::Object(
m.into_iter() m.into_iter()
.map(|(k, v)| (hashable_to_string(k), v.into_json_with_options(opt))) .map(|(k, v)| (hashable_to_string(k), v.into_json_with_options(opt)))
.collect(), .collect(),
), ),
crate::Value::List(l) => Value::Array( crate::Value::List(l) => serde_json::Value::Array(
l.into_iter() l.into_iter()
.map(|v| v.into_json_with_options(opt)) .map(|v| v.into_json_with_options(opt))
.collect(), .collect(),
), ),
crate::Value::None => Value::Null, crate::Value::None => serde_json::Value::Null,
} }
} }
} }
impl IntoJson for Primitive { impl IntoJson for Primitive {
fn into_json(self) -> Value { fn into_json(self) -> serde_json::Value {
match self { match self {
Primitive::Integer(i) => match i { Primitive::Integer(i) => match i {
crate::Integer::USize(n) => Value::Number(n.into()), crate::Integer::USize(n) => serde_json::Value::Number(n.into()),
crate::Integer::ISize(n) => Value::Number(n.into()), crate::Integer::ISize(n) => serde_json::Value::Number(n.into()),
crate::Integer::U8(n) => Value::Number(n.into()), crate::Integer::U8(n) => serde_json::Value::Number(n.into()),
crate::Integer::I8(n) => Value::Number(n.into()), crate::Integer::I8(n) => serde_json::Value::Number(n.into()),
crate::Integer::U16(n) => Value::Number(n.into()), crate::Integer::U16(n) => serde_json::Value::Number(n.into()),
crate::Integer::I16(n) => Value::Number(n.into()), crate::Integer::I16(n) => serde_json::Value::Number(n.into()),
crate::Integer::U32(n) => Value::Number(n.into()), crate::Integer::U32(n) => serde_json::Value::Number(n.into()),
crate::Integer::I32(n) => Value::Number(n.into()), crate::Integer::I32(n) => serde_json::Value::Number(n.into()),
crate::Integer::U64(n) => Value::Number(n.into()), crate::Integer::U64(n) => serde_json::Value::Number(n.into()),
crate::Integer::I64(n) => Value::Number(n.into()), crate::Integer::I64(n) => serde_json::Value::Number(n.into()),
crate::Integer::U128(n) => Value::Array(vec![ crate::Integer::U128(n) => serde_json::Value::Array(vec![
((n >> 64) as u64).into(), ((n >> 64) as u64).into(),
((n & 0xFFFFFFFFFFFFFFFF) as u64).into(), ((n & 0xFFFFFFFFFFFFFFFF) as u64).into(),
]), ]),
crate::Integer::I128(n) => Value::Array(vec![ crate::Integer::I128(n) => serde_json::Value::Array(vec![
((n >> 64) as i64).into(), ((n >> 64) as i64).into(),
((n & 0xFFFFFFFFFFFFFFFF) as u64).into(), ((n & 0xFFFFFFFFFFFFFFFF) as u64).into(),
]), ]),
}, },
Primitive::Float(f) => match f { Primitive::Float(f) => match f {
crate::Float::F32(f) => Number::from_f64(f as f64) crate::Float::F32(f) => Number::from_f64(f as f64)
.map(Value::Number) .map(serde_json::Value::Number)
.unwrap_or(Value::Null), .unwrap_or(serde_json::Value::Null),
crate::Float::F64(f) => Number::from_f64(f) crate::Float::F64(f) => Number::from_f64(f)
.map(Value::Number) .map(serde_json::Value::Number)
.unwrap_or(Value::Null), .unwrap_or(serde_json::Value::Null),
}, },
Primitive::String(s) => Value::String(s), Primitive::String(s) => serde_json::Value::String(s),
Primitive::OsString(o) => Value::String(o.to_string_lossy().into_owned()), Primitive::OsString(o) => serde_json::Value::String(o.to_string_lossy().into_owned()),
Primitive::Char(c) => Value::String(c.to_string()), Primitive::Char(c) => serde_json::Value::String(c.to_string()),
Primitive::Bool(b) => Value::Bool(b), Primitive::Bool(b) => serde_json::Value::Bool(b),
} }
} }
#[inline] #[inline]
fn into_json_with_options(self, _options: &IntoJsonOptions) -> Value { fn into_json_with_options(self, _options: &IntoJsonOptions) -> serde_json::Value {
self.into_json() self.into_json()
} }
} }
impl IntoJson for Enum { impl IntoJson for Enum {
#[inline] #[inline]
fn into_json(self) -> Value { fn into_json(self) -> serde_json::Value {
self.into_json_with_options(&IntoJsonOptions::default()) self.into_json_with_options(&IntoJsonOptions::default())
} }
fn into_json_with_options(self, opt: &IntoJsonOptions) -> Value { fn into_json_with_options(self, opt: &IntoJsonOptions) -> serde_json::Value {
let value = match self.fields { let value = match self.fields {
crate::Fields::Named(n) => Value::Object( crate::Fields::Named(n) => serde_json::Value::Object(
n.into_iter() n.into_iter()
.map(|(k, v)| (k, v.into_json_with_options(opt))) .map(|(k, v)| (k, v.into_json_with_options(opt)))
.collect(), .collect(),
@ -130,26 +129,29 @@ impl IntoJson for Enum {
if u.len() == 1 { if u.len() == 1 {
u.remove(0).into_json_with_options(opt) u.remove(0).into_json_with_options(opt)
} else { } else {
Value::Array( serde_json::Value::Array(
u.into_iter() u.into_iter()
.map(|v| v.into_json_with_options(opt)) .map(|v| v.into_json_with_options(opt))
.collect(), .collect(),
) )
} }
} }
crate::Fields::Unit => Value::String(self.variant.clone()), crate::Fields::Unit => serde_json::Value::String(self.variant.clone()),
}; };
match &opt.enum_repr { match &opt.enum_repr {
EnumRepr::Untagged => value, EnumRepr::Untagged => value,
EnumRepr::ExternallyTagged => { EnumRepr::ExternallyTagged => {
Value::Object([(self.variant, value)].into_iter().collect()) serde_json::Value::Object([(self.variant, value)].into_iter().collect())
} }
EnumRepr::AdjacentlyTagged { EnumRepr::AdjacentlyTagged {
type_field, type_field,
value_field, value_field,
} => Value::Object( } => serde_json::Value::Object(
[ [
(type_field.to_owned(), Value::String(self.variant)), (
type_field.to_owned(),
serde_json::Value::String(self.variant),
),
(value_field.to_owned(), value), (value_field.to_owned(), value),
] ]
.into_iter() .into_iter()
@ -161,12 +163,12 @@ impl IntoJson for Enum {
impl IntoJson for Struct { impl IntoJson for Struct {
#[inline] #[inline]
fn into_json(self) -> Value { fn into_json(self) -> serde_json::Value {
self.into_json_with_options(&IntoJsonOptions::default()) self.into_json_with_options(&IntoJsonOptions::default())
} }
fn into_json_with_options(self, opt: &IntoJsonOptions) -> Value { fn into_json_with_options(self, opt: &IntoJsonOptions) -> serde_json::Value {
match self.fields { match self.fields {
crate::Fields::Named(n) => Value::Object( crate::Fields::Named(n) => serde_json::Value::Object(
n.into_iter() n.into_iter()
.map(|(k, v)| (k, v.into_json_with_options(opt))) .map(|(k, v)| (k, v.into_json_with_options(opt)))
.collect(), .collect(),
@ -175,26 +177,26 @@ impl IntoJson for Struct {
if u.len() == 1 { if u.len() == 1 {
u.remove(0).into_json_with_options(opt) u.remove(0).into_json_with_options(opt)
} else { } else {
Value::Array( serde_json::Value::Array(
u.into_iter() u.into_iter()
.map(|v| v.into_json_with_options(opt)) .map(|v| v.into_json_with_options(opt))
.collect(), .collect(),
) )
} }
} }
crate::Fields::Unit => Value::String(self.name), crate::Fields::Unit => serde_json::Value::String(self.name),
} }
} }
} }
impl<R: RustyValue> IntoJson for R { impl<R: RustyValue> IntoJson for R {
#[inline] #[inline]
fn into_json(self) -> Value { fn into_json(self) -> serde_json::Value {
self.into_json_with_options(&IntoJsonOptions::default()) self.into_json_with_options(&IntoJsonOptions::default())
} }
#[inline] #[inline]
fn into_json_with_options(self, opt: &IntoJsonOptions) -> Value { fn into_json_with_options(self, opt: &IntoJsonOptions) -> serde_json::Value {
self.into_rusty_value().into_json_with_options(opt) self.into_rusty_value().into_json_with_options(opt)
} }
} }
@ -218,7 +220,7 @@ mod test {
use crate as rusty_value; use crate as rusty_value;
use crate::into_json::IntoJsonOptions; use crate::into_json::IntoJsonOptions;
use crate::RustyValue; use crate::*;
use super::IntoJson; use super::IntoJson;

Loading…
Cancel
Save