Debug, builder, hasher

Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
Luca Fulchir 2024-11-10 19:31:48 +01:00
parent dcd663126b
commit 103ba9b926
Signed by: luca.fulchir
GPG Key ID: 8F6440603D13A78E
7 changed files with 208 additions and 28 deletions

87
Cargo.lock generated
View File

@ -57,6 +57,15 @@ version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bok"
version = "0.1.0"
@ -66,6 +75,7 @@ dependencies = [
"paste",
"proc-macro2",
"quote",
"sha3",
]
[[package]]
@ -87,6 +97,7 @@ dependencies = [
"prettyplease",
"proc-macro2",
"quote",
"sha3",
"syn",
]
@ -138,6 +149,45 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "cpufeatures"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "heck"
version = "0.5.0"
@ -150,6 +200,21 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "keccak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
dependencies = [
"cpufeatures",
]
[[package]]
name = "libc"
version = "0.2.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
[[package]]
name = "paste"
version = "1.0.15"
@ -184,6 +249,16 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "sha3"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
dependencies = [
"digest",
"keccak",
]
[[package]]
name = "strsim"
version = "0.11.1"
@ -201,6 +276,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicase"
version = "2.8.0"
@ -225,6 +306,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "windows-sys"
version = "0.59.0"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2024 Luca Fulchir <luca.fulchir@runesauth.com>
*
* Licensed under the Apache License, Version 2.0 with LLVM exception (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License and of the exception at
* Licensed under the Apache License, Version 2.0 with LLVM exception (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License and of the exception at
*
* http://www.apache.org/licenses/LICENSE-2.0
* https://spdx.org/licenses/LLVM-exception.html
@ -51,8 +51,8 @@ pub fn repository(attrs: TokenStream, input: TokenStream) -> TokenStream {
}
}
/// Unless you know what you are doing, use `#[::bok::repository(MyBaseRepo)]` instead
/// needs a `.base` field
/// Unless you know what you are doing, use `#[::bok::repository(MyBaseRepo)]`
/// instead needs a `.base` field
///
/// Use like:
/// ```
@ -183,7 +183,7 @@ pub fn package(attrs: TokenStream, input: TokenStream) -> TokenStream {
}
quote! {
#[derive(::bok::Package)]
#[derive(::bok::Package,::std::fmt::Debug)]
#ast
}
.into()
@ -234,8 +234,8 @@ pub fn impl_package(_attrs: TokenStream, input: TokenStream) -> TokenStream {
.into()
}
/// Unless you know what you are doing, use `#[::bok::package(MyBasePackage)]` instead
/// needs a `.base` field
/// Unless you know what you are doing, use `#[::bok::package(MyBasePackage)]`
/// instead needs a `.base` field
///
/// ```
/// #[derive(::bok::Package)]
@ -255,6 +255,7 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
let name = input.ident.clone();
let name_builder = quote::format_ident!("{name}Builder");
let name_builder2 = name_builder.clone();
let name_builder3 = name_builder.clone();
let elements = match input.data {
::syn::Data::Struct(s) => match s.fields {
syn::Fields::Named(n) => n.named,
@ -385,6 +386,7 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
let non_opt_fields2 = non_opt_fields.clone();
let non_opt_fields3 = non_opt_fields.clone();
let non_opt_fields4 = non_opt_fields.clone();
let non_opt_fields5 = non_opt_fields.clone();
let opt_fields2 = opt_fields.clone();
let opt_fields3 = opt_fields.clone();
let opt_types2 = opt_types.clone();
@ -483,10 +485,21 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
}
}
impl #name {
pub fn builder() -> #name_builder {
#name_builder {
#(#all_fields : ::std::option::Option::None,)*
pub fn as_any(&self) -> &dyn ::std::any::Any {
self
}
pub fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
self
}
pub fn builder() -> #name_builder {
#name_builder::default()
}
pub fn hash() -> ::bok::Hash {
// FIXME: this does not capture the package field status
use ::sha3::{Digest, Sha3_256};
let mut hasher = ::sha3::Sha3_256::new();
let hash = hasher.finalize();
::bok::Hash::Sha3(hash)
}
#(pub fn #all_fields2(&self) -> &#all_types {
&self.#all_fields2
@ -495,6 +508,7 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
&mut self.#all_fields3
})*
}
#[derive(::std::default::Default, ::std::fmt::Debug)]
pub struct #name_builder {
#(#non_opt_fields: ::std::option::Option<#non_opt_types>,)*
#(#opt_fields: ::std::option::Option<#opt_types>,)*
@ -507,8 +521,15 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
}
}
*/
impl #name_builder2 {
pub fn build(&mut self) -> Result<#name, ::std::boxed::Box<dyn ::std::error::Error>> {
impl ::bok::PkgBuilder for #name_builder2 {
type Package = #name;
fn default_unused(&mut self){
let def = #name::default();
#(if self.#non_opt_fields5.is_none() {
self.#non_opt_fields5 = Some(def.#non_opt_fields5);
})*
}
fn build(&mut self) -> Result<#name, ::std::boxed::Box<dyn ::std::error::Error>> {
#(if self.#non_opt_fields2.is_none() {
return ::std::result::Result::Err("unset field".into());
})*
@ -521,11 +542,37 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
}
)
}
}
impl #name_builder3 {
pub fn as_any(&self) -> &dyn ::std::any::Any {
self
}
pub fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
self
}
pub fn as_builder(&self) -> &dyn ::bok::PkgBuilder<Package = #name> {
self
}
pub fn as_builder_mut(&mut self) -> &mut dyn ::bok::PkgBuilder<Package = #name> {
self
}
#(pub fn #non_opt_fields4 (&mut self, val : #non_opt_types2) -> &mut Self {
if self.#non_opt_fields4 != None &&
self.#non_opt_fields4 != Some(val) {
panic!("Package \"{}\": mandatory attribute set multiple times: \"{}\"",
::std::stringify!(#name),
::std::stringify!(#non_opt_fields4));
}
self.#non_opt_fields4 = Some(val);
self
})*
#(pub fn #opt_fields3 (&mut self, val : #opt_types2) -> &mut Self {
if self.#opt_fields3 != None &&
self.#opt_fields3 != Some(val) {
panic!("Package \"{}\": optional attribute set multiple times: \"{}\"",
::std::stringify!(#name),
::std::stringify!(#opt_fields3));
}
self.#opt_fields3 = Some(val);
self
})*

View File

@ -17,3 +17,4 @@ proc-macro2 = "1.0"
quote = "1.0"
prettyplease = "0.2"
syn = { version = "2", features = [ "full", "parsing" ] }
sha3 = { version = "0.10" }

View File

@ -18,15 +18,42 @@
mod conf;
mod pkgs;
/*
trait TP {
fn p(r: &impl TR);
}
trait TR {
fn r();
}
struct R {}
impl TR for R {
fn r() {}
}
struct P {}
impl TP for P {
fn p(r: &impl TR) {}
}
*/
fn main() {
let pkgs1 = pkgs::Pkgs1::default();
let pkgs2 = pkgs::Pkgs2::default();
let mut pb: pkgs::one::OneBuilder = pkgs1.one_builder();
let b = pb.as_builder();
let a = pb.as_any_mut();
let m_pb2: Option<&mut pkgs::one::OneBuilder> = a.downcast_mut();
println!("m_pb2: {:?}", m_pb2);
println!("pkgs1 - 1:{}", pkgs1.one().my_attr);
println!("pkgs1 - 2:{}", pkgs1.two().my_attr);
println!("pkgs2 - 1:{}", pkgs2.one().my_attr);
println!("pkgs2 - 2:{}", pkgs2.two().my_attr);
println!("pkgs2 - 3:{}", pkgs2.three().my_attr);
println!("pkgs1:\n{}", pkgs1.one());
println!("pkgs2-1:\n{}", pkgs2.one());
println!("pkgs2-2:\n{}", pkgs2.two());
println!("pkgs2-3:\n{}", pkgs2.three());
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2024 Luca Fulchir <luca.fulchir@runesauth.com>
*
* Licensed under the Apache License, Version 2.0 with LLVM exception (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License and of the exception at
* Licensed under the Apache License, Version 2.0 with LLVM exception (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License and of the exception at
*
* http://www.apache.org/licenses/LICENSE-2.0
* https://spdx.org/licenses/LLVM-exception.html
@ -18,7 +18,6 @@
//!
//! Example of two package repositories, where one
//! extends ancd changes another
//!
// Export multiple packages in this module
bok::moduse! {
@ -29,7 +28,6 @@ bok::moduse! {
///
/// Base repository with some packages
///
#[::bok_macro::repository(::bok::RepositoryEmpty)]
#[derive(::std::default::Default)]
pub struct Pkgs1 {}
@ -45,7 +43,6 @@ bok::repo_packages! {
///
/// This repository extends and changes Pkgs1
///
#[::bok_macro::repository(Pkgs1)]
#[derive(::std::default::Default)]
pub struct Pkgs2 {}
@ -60,6 +57,7 @@ bok::repo_packages! {
impl Pkgs2 {
/// override the package `two` options from the base repostiory (Pkgs1)
pub fn two(&self) -> Two {
use ::bok::PkgBuilder;
Two::builder()
.my_attr(42)
.build()

View File

@ -19,3 +19,4 @@ bitflags = "2.4"
proc-macro2 = "1.0"
quote = "1.0"
bok-macro = { path="../bok-macro" }
sha3 = { version = "0.10" }

View File

@ -1,9 +1,9 @@
/*
* Copyright 2024 Luca Fulchir <luca.fulchir@runesauth.com>
*
* Licensed under the Apache License, Version 2.0 with LLVM exception (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License and of the exception at
* Licensed under the Apache License, Version 2.0 with LLVM exception (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License and of the exception at
*
* http://www.apache.org/licenses/LICENSE-2.0
* https://spdx.org/licenses/LLVM-exception.html
@ -28,9 +28,9 @@ pub use ::bok_macro::{
macro_rules! moduse {
($($name:ident,)*) => {
$(
mod $name;
pub mod $name;
#[allow(unused_imports)]
use $name::*;
pub use $name::*;
)*
};
}
@ -70,6 +70,9 @@ macro_rules! packages {
pub fn [<$name:snake>] (&self) -> $name {
$name::default()
}
pub fn [<$name:snake _builder>] (&self) -> [<$name Builder>] {
$name::builder()
}
)*
}
};
@ -80,13 +83,17 @@ pub trait Repository: Default {}
///
/// This is an empty Package List. Will be available in the main library
///
#[derive(::std::default::Default)]
pub struct RepositoryEmpty {}
impl Repository for RepositoryEmpty {}
/// Implement common package operations
pub trait Pkg: ::std::default::Default + ::core::fmt::Display {
pub trait Pkg:
::std::default::Default
+ ::core::fmt::Debug
+ ::core::fmt::Display
+ ::std::any::Any
{
fn base(&self) -> ::core::option::Option<&impl Pkg>;
fn prepare(&self) -> ::core::result::Result<(), ()> {
self.base().unwrap().prepare()
@ -137,7 +144,15 @@ pub trait Pkg: ::std::default::Default + ::core::fmt::Display {
}
}
#[derive(Default)]
pub trait PkgBuilder: ::std::any::Any {
type Package;
fn default_unused(&mut self);
fn build(
&mut self,
) -> Result<Self::Package, ::std::boxed::Box<dyn ::std::error::Error>>;
}
#[derive(Default, Debug)]
pub struct PkgEmpty {}
impl ::core::fmt::Display for PkgEmpty {
@ -223,6 +238,10 @@ impl Pkg for PkgEmpty {
// Conf stuff
pub struct Conf {}
/// package hash
pub enum Hash {
Sha3(::sha3::digest::Output<::sha3::Sha3_256>),
}
/*
pub enum Value<T: Sized> {
/// Set, only once per