Skip to content

Commit

Permalink
WIP (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
loganmzz committed Aug 12, 2024
1 parent 699fcc5 commit cace3f8
Show file tree
Hide file tree
Showing 13 changed files with 1,821 additions and 43 deletions.
35 changes: 35 additions & 0 deletions macon-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,41 @@
}
}
}
},
"extend_types": {
"description": "Override pathes that should implement Extend",
"type": "object",
"properties": {
"includes": {
"description": "Pathes that should implement Extend",
"type": "array",
"items": {
"oneOf": [
{
"description": "Path that should implement Extend",
"type": "string"
},
{
"description": "Path and associated wrapped type",
"type": "object",
"properties": {
"path": {
"description": "Path that should implement Extend",
"type": "string"
},
"wrapped": {
"description": "Contained type",
"type": "string"
},
"required": [
"path"
]
}
}
]
}
}
}
}
}
}
70 changes: 69 additions & 1 deletion macon_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
//! See it for all details.
//!
use std::fmt::Debug;
use std::{
fmt::Debug, ops::Deref, vec
};

/// Builder field type when building struct implementing [`Default`].
#[derive(Default,)]
Expand All @@ -25,6 +27,14 @@ pub enum Defaulting<T: Default> {
Set(T),
}

/// Builder field type when target implment [`Extend`].
pub struct Extending<C,I> {
/// Collecting items
items: Vec<I>,
/// Building value
value: C,
}

/// Builder field type for `Panic` or `Result` mode.
#[derive(Default,)]
pub enum Building<T> {
Expand Down Expand Up @@ -82,6 +92,64 @@ impl<T: Default> Defaulting<T> {
}
}

impl<C, I> Default for Extending<C, I> where C: Default {
fn default() -> Self {
Self {
items: Default::default(),
value: Default::default(),
}
}
}

impl<C, I> Deref for Extending<C, I> {
type Target = C;

fn deref(&self) -> &Self::Target {
&self.value
}
}

impl<C, I> Extend<I> for Extending<C, I> {
/// Store `iter` values into `items` (until container is created)
fn extend<T: IntoIterator<Item = I>>(&mut self, iter: T) {
self.items.extend(iter)
}
}

impl<C, I> IntoIterator for Extending<C, I> {
type Item = I;
type IntoIter = vec::IntoIter<I>;
fn into_iter(self) -> Self::IntoIter {
self.items.into_iter()
}
}

impl<C, I> Extending<C, I> {
pub fn with_value(self, value: C) -> Self {
Self {
value,
items: self.items,
}
}

pub fn value_mut(&mut self) -> &mut C {
&mut self.value
}

/// Consume to return `value` and collected `items`.
pub fn unwrap(self) -> (C, Vec<I>) {
(self.value, self.items)
}

/// Consume to return built collection extracting `value` and extending with ìtems.
pub fn unwrap_with<IS: Extend<I>, F: FnOnce(C)->IS>(self, f: F) -> IS {
let Self { value, items } = self;
let mut unwrapped = f(value);
unwrapped.extend(items);
unwrapped
}
}

impl<T> Debug for Building<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expand Down
60 changes: 60 additions & 0 deletions macon_derive/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use std::{
fmt::{
Debug,
Display,
},
ops::Deref,
};
use quote::ToTokens;
use syn::Type;

pub struct TokenDisplay<T: ToTokens>(T);

pub type MType = TokenDisplay<Type>;

impl<T: ToTokens> Debug for TokenDisplay<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{}", self))
}
}

impl<T: ToTokens> Display for TokenDisplay<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{}", self.0.to_token_stream()))
}
}

impl<T: ToTokens> From<T> for TokenDisplay<T> {
fn from(value: T) -> Self {
Self(value)
}
}

impl<T: ToTokens> Deref for TokenDisplay<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<T: ToTokens> ToTokens for TokenDisplay<T> {
fn to_token_stream(&self) -> proc_macro2::TokenStream {
self.0.to_token_stream()
}

fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
self.0.to_tokens(tokens)
}

fn into_token_stream(self) -> proc_macro2::TokenStream
where
Self: Sized, {
self.0.into_token_stream()
}
}

impl<T: ToTokens + PartialEq> PartialEq<T> for TokenDisplay<T> {
fn eq(&self, other: &T) -> bool {
self.0.eq(other)
}
}
Loading

0 comments on commit cace3f8

Please sign in to comment.