oct/oct-macros/src/impl_derive_macro.rs
Gabriel Bjørnager Jensen 12975eabf5 Reimplement 'Decode' for 'alloc::vec::Vec', 'alloc::string::String', 'CString', 'LinkedList', 'HashMap', and 'HashSet'; Reimplement 'DecodeBorrowed' for 'alloc::vec::Vec', 'alloc::string::String', and 'CString'; Update and add tests; Update readme; Clean up code; Implement 'From<Infallible>' for all error types; Update docs; Rework 'EnumEncodeError' and 'EnumDecodeError'; Add 'encode_char' benchmark; Implement 'Encode' and 'Decode' for 'OsStr', 'OsString', 'c_void', and 'BinaryHeap'; Remove 'never-type' feature flag; Rework 'PrimDiscriminant' as 'PrimRepr'; Add 'PrimDiscriminant' enumeration; Implement 'From<T: PrimRepr>' for 'PrimDiscriminant'; Implement 'PrimRepr' for 'u8', 'u16', 'u32', 'u64', 'u128', 'usize', 'i8', 'i16', 'i32', 'i64', 'i128', and 'isize'; Implement 'Debug', 'Display', 'Binary', 'Octal', 'LowerHex', 'UpperHex', 'LowerExp', and 'UpperExp' for 'PrimDiscriminant'; Implement 'Clone', 'Copy', 'Eq', 'PartialEq', and 'Hash' for 'PrimDiscriminant'; Implement 'Eq' and 'PartialEq' for **all** error types; Add 'as_slice' and 'as_ptr' methods to 'Input'; Implement 'AsRef<[u8]>' and 'Borrow<[u8]>' for 'Input'; Implement 'SizedEncode' for 'c_void'; Fix '<LinkedList as Encode>::Error'; Add 'new_unchecked' constructor to 'String' and 'Vec'; Rework 'from_utf8' and 'from_utf8_unchecked' in 'String'; Remove 'StringError'; Rework 'String' to make it trivially-destructable; Actually mark 'String::as_mut_str' with 'const'; Unimplement 'PartialOrd<{&str, alloc::string::String}>' for 'String'; Implement 'PartialEq<str>' for 'String'; Unimplement 'PartialOrd<{[T; M], &[T], alloc::vec::Vec<T>}>' for 'Vec<T, N>'; Remove 'is_full' method from 'String' and 'Vec'; Implement 'Copy' for 'String'; Implement 'PartialEq<{Self, [u8], &[u8]}>', 'Eq', and 'Debug' for 'Input'; Implement 'PartialEq<[U]>' for 'Vec<T, ..>'; Implement 'PartialEq<Vec<U, ..>>' for 'alloc::vec::Vec<T>'; Implement 'PartialEq<String>' for 'alloc::string::String'; Add 'is_char_boundary' and 'as_mut_bytes' methods to 'String'; Add doc aliases; Update lints; Fix atomics being imported from 'std';
2025-01-14 21:58:12 +01:00

67 lines
No EOL
1.4 KiB
Rust

// Copyright 2024-2025 Gabriel Bjørnager Jensen.
//
// This Source Code Form is subject to the terms of
// the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, you
// can obtain one at:
// <https://mozilla.org/MPL/2.0/>.
use crate::{GenericName, Repr};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{
Data,
DataEnum,
DataStruct,
DeriveInput,
Path,
Token,
};
pub fn impl_derive_macro<S, E>(
input: DeriveInput,
trait_path: Path,
unsafe_token: Option<Token![unsafe]>,
struct_body: S,
enum_body: E,
) -> TokenStream
where
S: FnOnce(DataStruct) -> TokenStream,
E: FnOnce(DataEnum, Repr) -> TokenStream,
{
let trait_name = &trait_path
.segments
.last()
.expect("expected non-empty path for derived trait")
.ident;
let self_name = &input.ident;
let body = match input.data {
Data::Struct(data) => struct_body(data),
Data::Enum(data) => {
let repr = Repr::get(&input.attrs).unwrap_or_default();
enum_body(data, repr)
}
Data::Union(..) => panic!("unions cannot derive `{trait_name}`"),
};
let generic_params = &input.generics.params;
let generic_where = &input.generics.where_clause;
let generic_names = GenericName::extract_from(&input.generics);
let output = quote! {
#unsafe_token impl<#generic_params> #trait_path for #self_name<#generic_names>
#generic_where
{
#body
}
};
output
}