Skip to content

Commit

Permalink
feat: validate the element amount in tuples
Browse files Browse the repository at this point in the history
A valid tuple type must have between 2 and 12 elements. Empty tuples
carry no data at all, tuples with one element are equivalent to the type
of that single element and tuples with 13 or more elements are above a
reasonable limit.
  • Loading branch information
dnaka91 committed Nov 3, 2023
1 parent 6f9e8ab commit abcee05
Show file tree
Hide file tree
Showing 59 changed files with 1,645 additions and 395 deletions.
20 changes: 11 additions & 9 deletions crates/stef-build/src/decode.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
use stef_parser::{DataType, Enum, Fields, Generics, NamedField, Struct, UnnamedField, Variant};
use stef_parser::{
DataType, Enum, Fields, Generics, NamedField, Struct, Type, UnnamedField, Variant,
};

pub fn compile_struct(
Struct {
Expand Down Expand Up @@ -125,7 +127,7 @@ fn compile_field_vars(fields: &Fields<'_>) -> TokenStream {
let vars = vars.map(|(name, ty)| {
let ty_ident = super::definition::compile_data_type(ty);

if matches!(ty, DataType::Option(_)) {
if matches!(ty.value, DataType::Option(_)) {
quote! { let mut #name: #ty_ident = None; }
} else {
quote! { let mut #name: Option<#ty_ident> = None; }
Expand All @@ -148,7 +150,7 @@ fn compile_field_matches(fields: &Fields<'_>) -> TokenStream {
}| {
let id = proc_macro2::Literal::u32_unsuffixed(id.get());
let name = proc_macro2::Ident::new(name.get(), Span::call_site());
let ty = compile_data_type(if let DataType::Option(ty) = ty {
let ty = compile_data_type(if let DataType::Option(ty) = &ty.value {
ty
} else {
ty
Expand All @@ -167,7 +169,7 @@ fn compile_field_matches(fields: &Fields<'_>) -> TokenStream {
.map(|(idx, UnnamedField { ty, id, .. })| {
let id = proc_macro2::Literal::u32_unsuffixed(id.get());
let name = Ident::new(&format!("n{idx}"), Span::call_site());
let ty = compile_data_type(if let DataType::Option(ty) = ty {
let ty = compile_data_type(if let DataType::Option(ty) = &ty.value {
ty
} else {
ty
Expand All @@ -190,7 +192,7 @@ fn compile_field_assigns(fields: &Fields<'_>) -> TokenStream {
let name_lit = proc_macro2::Literal::string(named.name.get());
let id = proc_macro2::Literal::u32_unsuffixed(named.id.get());

if matches!(named.ty, DataType::Option(_)) {
if matches!(named.ty.value, DataType::Option(_)) {
quote! { #name }
} else {
quote! { #name: #name.ok_or(::stef::buf::Error::MissingField {
Expand All @@ -207,7 +209,7 @@ fn compile_field_assigns(fields: &Fields<'_>) -> TokenStream {
let name = Ident::new(&format!("n{idx}"), Span::call_site());
let id = proc_macro2::Literal::u32_unsuffixed(unnamed.id.get());

if matches!(unnamed.ty, DataType::Option(_)) {
if matches!(unnamed.ty.value, DataType::Option(_)) {
quote! { #name }
} else {
quote! { #name.ok_or(::stef::buf::Error::MissingField {
Expand Down Expand Up @@ -240,8 +242,8 @@ fn compile_generics(Generics(types): &Generics<'_>) -> (TokenStream, TokenStream
}

#[allow(clippy::needless_pass_by_value)]
fn compile_data_type(ty: &DataType<'_>) -> TokenStream {
match ty {
fn compile_data_type(ty: &Type<'_>) -> TokenStream {
match &ty.value {
DataType::Bool => quote! { ::stef::buf::decode_bool(r) },
DataType::U8 => quote! { ::stef::buf::decode_u8(r) },
DataType::U16 => quote! { ::stef::buf::decode_u16(r) },
Expand Down Expand Up @@ -274,7 +276,7 @@ fn compile_data_type(ty: &DataType<'_>) -> TokenStream {
let ty = compile_data_type(ty);
quote! { ::stef::buf::decode_option(r, |r| { #ty }) }
}
DataType::NonZero(ty) => match &**ty {
DataType::NonZero(ty) => match &ty.value {
DataType::U8 => quote! { ::stef::buf::decode_non_zero_u8(r) },
DataType::U16 => quote! { ::stef::buf::decode_non_zero_u16(r) },
DataType::U32 => quote! { ::stef::buf::decode_non_zero_u32(r) },
Expand Down
17 changes: 7 additions & 10 deletions crates/stef-build/src/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use proc_macro2::{Ident, Span, TokenStream};
use quote::{quote, ToTokens};
use stef_parser::{
Comment, Const, DataType, Definition, Enum, ExternalType, Fields, Generics, Import, Literal,
Module, Name, NamedField, Schema, Struct, TypeAlias, UnnamedField, Variant,
Module, Name, NamedField, Schema, Struct, Type, TypeAlias, UnnamedField, Variant,
};

use super::{decode, encode};
Expand Down Expand Up @@ -215,10 +215,7 @@ fn compile_fields(fields: &Fields<'_>, for_struct: bool) -> TokenStream {
Fields::Named(named) => {
let fields = named.iter().map(
|NamedField {
comment,
name,
ty,
..
comment, name, ty, ..
}| {
let comment = compile_comment(comment);
let public = for_struct.then(|| quote! { pub });
Expand Down Expand Up @@ -258,8 +255,8 @@ fn compile_fields(fields: &Fields<'_>, for_struct: bool) -> TokenStream {
}
}

pub(super) fn compile_data_type(ty: &DataType<'_>) -> TokenStream {
match ty {
pub(super) fn compile_data_type(ty: &Type<'_>) -> TokenStream {
match &ty.value {
DataType::Bool => quote! { bool },
DataType::U8 => quote! { u8 },
DataType::U16 => quote! { u16 },
Expand Down Expand Up @@ -292,7 +289,7 @@ pub(super) fn compile_data_type(ty: &DataType<'_>) -> TokenStream {
let ty = compile_data_type(ty);
quote! { Option<#ty> }
}
DataType::NonZero(ty) => match &**ty {
DataType::NonZero(ty) => match &ty.value {
DataType::U8 => quote! { ::std::num::NonZeroU8 },
DataType::U16 => quote! { ::std::num::NonZeroU16 },
DataType::U32 => quote! { ::std::num::NonZeroU32 },
Expand Down Expand Up @@ -350,8 +347,8 @@ pub(super) fn compile_data_type(ty: &DataType<'_>) -> TokenStream {
}
}

fn compile_const_data_type(ty: &DataType<'_>) -> TokenStream {
match ty {
fn compile_const_data_type(ty: &Type<'_>) -> TokenStream {
match &ty.value {
DataType::Bool => quote! { bool },
DataType::U8 => quote! { u8 },
DataType::U16 => quote! { u16 },
Expand Down
30 changes: 16 additions & 14 deletions crates/stef-build/src/encode.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
use stef_parser::{DataType, Enum, Fields, Generics, NamedField, Struct, UnnamedField, Variant};
use stef_parser::{
DataType, Enum, Fields, Generics, NamedField, Struct, Type, UnnamedField, Variant,
};

pub fn compile_struct(
Struct {
Expand Down Expand Up @@ -45,8 +47,8 @@ fn compile_struct_fields(fields: &Fields<'_>) -> TokenStream {
let id = proc_macro2::Literal::u32_unsuffixed(id.get());
let name = proc_macro2::Ident::new(name.get(), Span::call_site());

if let DataType::Option(ty) = ty {
let ty = compile_data_type(ty, if is_copy(ty) {
if let DataType::Option(ty) = &ty.value {
let ty = compile_data_type(ty, if is_copy(&ty.value) {
quote! { *v }
} else {
quote! { v }
Expand Down Expand Up @@ -177,7 +179,7 @@ fn compile_variant_fields(fields: &Fields<'_>) -> TokenStream {
let id = proc_macro2::Literal::u32_unsuffixed(id.get());
let name = proc_macro2::Ident::new(name.get(), Span::call_site());

if matches!(ty, DataType::Option(_)) {
if matches!(ty.value, DataType::Option(_)) {
quote! { ::stef::buf::encode_field_option(w, #id, &#name); }
} else {
let ty = compile_data_type(ty, quote! { *#name });
Expand Down Expand Up @@ -248,8 +250,8 @@ fn is_copy(ty: &DataType<'_>) -> bool {
}

#[allow(clippy::needless_pass_by_value, clippy::too_many_lines)]
fn compile_data_type(ty: &DataType<'_>, name: TokenStream) -> TokenStream {
match ty {
fn compile_data_type(ty: &Type<'_>, name: TokenStream) -> TokenStream {
match &ty.value {
DataType::Bool => quote! { ::stef::buf::encode_bool(w, #name) },
DataType::U8 => quote! { ::stef::buf::encode_u8(w, #name) },
DataType::U16 => quote! { ::stef::buf::encode_u16(w, #name) },
Expand All @@ -268,7 +270,7 @@ fn compile_data_type(ty: &DataType<'_>, name: TokenStream) -> TokenStream {
DataType::Vec(ty) => {
let ty = compile_data_type(
ty,
if is_copy(ty) {
if is_copy(&ty.value) {
quote! { *v }
} else {
quote! { v }
Expand All @@ -279,15 +281,15 @@ fn compile_data_type(ty: &DataType<'_>, name: TokenStream) -> TokenStream {
DataType::HashMap(kv) => {
let ty_k = compile_data_type(
&kv.0,
if is_copy(&kv.0) {
if is_copy(&kv.0.value) {
quote! { *k }
} else {
quote! { k }
},
);
let ty_v = compile_data_type(
&kv.1,
if is_copy(&kv.1) {
if is_copy(&kv.1.value) {
quote! { *v }
} else {
quote! { v }
Expand All @@ -298,7 +300,7 @@ fn compile_data_type(ty: &DataType<'_>, name: TokenStream) -> TokenStream {
DataType::HashSet(ty) => {
let ty = compile_data_type(
ty,
if is_copy(ty) {
if is_copy(&ty.value) {
quote! { *v }
} else {
quote! { v }
Expand All @@ -309,15 +311,15 @@ fn compile_data_type(ty: &DataType<'_>, name: TokenStream) -> TokenStream {
DataType::Option(ty) => {
let ty = compile_data_type(
ty,
if is_copy(ty) {
if is_copy(&ty.value) {
quote! { *v }
} else {
quote! { v }
},
);
quote! { ::stef::buf::encode_option(w, &#name, |w, v| { #ty; }) }
}
DataType::NonZero(ty) => match &**ty {
DataType::NonZero(ty) => match &ty.value {
DataType::U8 => quote! { ::stef::buf::encode_u8(w, #name.get()) },
DataType::U16 => quote! { ::stef::buf::encode_u16(w, #name.get()) },
DataType::U32 => quote! { ::stef::buf::encode_u32(w, #name.get()) },
Expand Down Expand Up @@ -346,7 +348,7 @@ fn compile_data_type(ty: &DataType<'_>, name: TokenStream) -> TokenStream {
let idx = proc_macro2::Literal::usize_unsuffixed(idx);
compile_data_type(
ty,
if is_copy(ty) {
if is_copy(&ty.value) {
quote! { #name.#idx }
} else {
quote! { &(#name.#idx) }
Expand All @@ -362,7 +364,7 @@ fn compile_data_type(ty: &DataType<'_>, name: TokenStream) -> TokenStream {
DataType::Array(ty, _size) => {
let ty = compile_data_type(
ty,
if is_copy(ty) {
if is_copy(&ty.value) {
quote! { *v }
} else {
quote! { v }
Expand Down
10 changes: 9 additions & 1 deletion crates/stef-compiler/src/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ pub fn value(value: impl Display) -> String {
if cfg!(feature = "debug") {
format!("❬Y❭{value}❬Y❭")
} else {
value.bright_yellow().bold().to_string()
value.bright_yellow().to_string()
}
}

pub fn focus(value: impl Display) -> String {
if cfg!(feature = "debug") {
format!("❬W❭{value}❬W❭")
} else {
value.bright_white().to_string()
}
}
Loading

0 comments on commit abcee05

Please sign in to comment.