Add more benchmarks; Redefine 'bool' scheme; Remove 'BoolDecodeError'; Rename project to *oct*; Rename 'librum' crate to 'oct'; Rename 'librum-macros' crate to 'oct-macros'; Rename 'librum-benchmarks' crate to 'oct-benchmarks'; Update lints; Update logo; Restructure tests; Rename 'IStream' to 'Input'; Rename 'OStream' to 'Output'; Make 'Output::write' and 'Input::{read, read_into}' fallible; Add 'OutputError' and 'InputError' error types; Mark 'Output::write' and 'Input::{read, read_into}' with 'const'; Add 'position', 'capacity', and 'remaining' methods to 'Output' and 'Input'; Rename 'SizeError' to 'LengthError'; Rework some error types; Fix feature flags for 'From<CStringDecodeError>' for 'GenericDecodeError'; Rename 'Buf' to 'Slot'; Remove '{Output, Input}::close'; Implement 'AsRef<[u8]>', 'Borrow<[u8]>', 'PartialEq<{Self, [u8], &[u8], &mut [u8]}>', and 'Eq' for 'Output'; Add 'as_slice' and 'as_ptr' methods to 'Output'; Add 'encode' and 'decode' modules; Update homepage link; Refactor code; Update readme;

This commit is contained in:
Gabriel Bjørnager Jensen 2024-12-20 11:40:26 +01:00
parent ef4b3c269a
commit b6f171e913
74 changed files with 1759 additions and 1445 deletions

View file

@ -0,0 +1,94 @@
// Copyright 2024 Gabriel Bjørnager Jensen.
//
// This file is part of oct.
//
// oct is free software: you can redistribute it
// and/or modify it under the terms of the GNU
// Lesser General Public License as published by
// the Free Software Foundation, either version 3
// of the License, or (at your option) any later
// version.
//
// oct is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY; without
// even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Less-
// er General Public License along with oct. If
// not, see <https://www.gnu.org/licenses/>.
use crate::{Discriminants, Repr};
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{DataEnum, Fields, Ident, LitInt};
#[must_use]
pub fn encode_enum(data: DataEnum, repr: Repr) -> TokenStream {
let discriminants: Vec<LitInt> = Discriminants::new(&data.variants).collect();
let captures: Vec<Vec<Ident>> = data
.variants
.iter()
.map(|variant| {
variant
.fields
.iter()
.enumerate()
.map(|(index, _)| Ident::new(&format!("value{index}"), Span::call_site()))
.collect()
})
.collect();
let patterns = data
.variants
.into_iter()
.zip(&captures)
.map(|(variant, captures)| {
let variant_name = variant.ident;
match variant.fields {
Fields::Unit => quote! { Self::#variant_name },
Fields::Unnamed(_fields) => quote! { Self::#variant_name (#(ref #captures, )*) },
Fields::Named(fields) => {
let field_names = fields
.named
.into_iter()
.map(|field| field.ident.unwrap());
quote! { Self::#variant_name { #(#field_names: ref #captures, )* } }
},
}
});
quote! {
type Error = ::oct::error::EnumEncodeError<#repr, ::oct::error::GenericEncodeError>;
#[allow(unreachable_patterns)]
#[inline]
fn encode(&self, stream: &mut ::oct::encode::Output) -> ::core::result::Result<(), Self::Error> {
match *self {
#(
#patterns => {
<#repr as ::oct::encode::Encode>::encode(&#discriminants, stream)
.map_err(::oct::error::EnumEncodeError::BadDiscriminant)?;
#(
::oct::encode::Encode::encode(#captures, stream)
.map_err(::core::convert::Into::<::oct::error::GenericEncodeError>::into)
.map_err(::oct::error::EnumEncodeError::BadField)?;
)*
}
)*
_ => ::core::unreachable!("no variants defined for this enumeration"),
}
::core::result::Result::Ok(())
}
}
}