Skip to content

Commit

Permalink
feat: add proc macro for expanding config structs and borders config
Browse files Browse the repository at this point in the history
  • Loading branch information
pintariching committed Apr 28, 2023
1 parent 0a4189d commit bfdf644
Show file tree
Hide file tree
Showing 16 changed files with 398 additions and 164 deletions.
35 changes: 28 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["railwind", "railwind_cli"]
members = ["railwind", "railwind_cli", "get_derive"]

[profile.small]
inherits = 'release'
Expand Down
12 changes: 12 additions & 0 deletions get_derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "get_derive"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

[dependencies]
quote = "1.0.26"
syn = { version = "2.0.13", features = [ "full" ] }
proc-macro2 = "1.0.56"
65 changes: 65 additions & 0 deletions get_derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Expr, Fields, Lit};

#[proc_macro_derive(GetOnceCell, attributes(config_path))]
pub fn derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

let fields = match &input.data {
Data::Struct(DataStruct {
fields: Fields::Named(fields),
..
}) => &fields.named,
_ => panic!("expected a struct with named fields"),
};

let field_name = fields.iter().map(|f| &f.ident);
let field_fn_name = fields.iter().map(|field| {
if let Some(ident) = &field.ident {
let name = format!("get_{}", ident.to_string());
Some(proc_macro2::Ident::new(&name, ident.span()))
} else {
None
}
});

let field_mut_fn_name = fields.iter().map(|field| {
if let Some(ident) = &field.ident {
let name = format!("get_mut_{}", ident.to_string());
Some(proc_macro2::Ident::new(&name, ident.span()))
} else {
None
}
});

let config_path = fields.iter().map(|f| {
if let Some(attr) = f.attrs.first() {
if attr.path().is_ident("config_path") {
let path: Lit = attr.parse_args().unwrap();
Some(path)
} else {
None
}
} else {
None
}
});

let struct_name = &input.ident;

TokenStream::from(quote! {
impl #struct_name {
#(
pub fn #field_fn_name(&self) -> &::std::collections::HashMap<&'static str, &'static str> {
self.#field_name.get_or_init(|| ron::from_str(include_str!(#config_path)).unwrap())
}

pub fn #field_mut_fn_name(&mut self) -> &mut ::std::collections::HashMap<&'static str, &'static str> {
let _ = self.#field_fn_name();
self.#field_name.get_mut().unwrap()
}
)*
}
})
}
1 change: 1 addition & 0 deletions railwind/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ indexmap = "1.9.2"
serde = { version = "1.0.152", features = ["derive"] }

nom = "7.1.3"
get_derive = { path = "../get_derive" }

[dev-dependencies]
walkdir = "2.3.2"
12 changes: 6 additions & 6 deletions railwind/src/class/backgrounds/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use nom::IResult;

use crate::class::utils::{arbitrary, hex_to_rgb_color, keyword_dash};
use crate::class::{Decl, IntoDeclaration};
use crate::Config;
use crate::config::Config;

use super::utils::{hashmap_value, keyword_value};

Expand Down Expand Up @@ -302,7 +302,7 @@ mod tests {
#[test]
fn test_attachment() {
assert_eq!(
background("bg-fixed", &Config::new()),
backgrounds("bg-fixed", &Config::new()),
Ok((
"",
Backgrounds::BackgroundAttachment(BackgroundAttachment::Fixed)
Expand All @@ -313,15 +313,15 @@ mod tests {
#[test]
fn test_clip() {
assert_eq!(
background("bg-content", &Config::new()),
backgrounds("bg-content", &Config::new()),
Ok(("", Backgrounds::BackgroundClip(BackgroundClip::Content)))
);
}

#[test]
fn test_color() {
assert_eq!(
background("bg-red-500", &Config::new()),
backgrounds("bg-red-500", &Config::new()),
Ok(("", Backgrounds::BackgroundColor(BackgroundColor("#ef4444"))))
);
}
Expand All @@ -330,10 +330,10 @@ mod tests {
fn test_config() {
let mut c = Config::new();

c.get_mut_backgrounds().color.insert("yellow", "#yellow");
c.backgrounds.get_mut_color().insert("yellow", "#yellow");

assert_eq!(
background("bg-yellow", &c),
backgrounds("bg-yellow", &c),
Ok(("", Backgrounds::BackgroundColor(BackgroundColor("#yellow"))))
);
}
Expand Down
134 changes: 116 additions & 18 deletions railwind/src/class/borders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,122 @@
// ron::from_str(include_str!("../colors.ron")).unwrap();
// }

// #[derive(Debug, PartialEq, Hash)]
// pub enum Borders<'a> {
// BorderRadius(BorderRadius<'a>),
// BorderWidth(BorderWidth<'a>),
// BorderColor(BorderColor<'a>),
// BorderStyle(BorderStyle),
// DivideWidth(DivideWidth<'a>),
// DivideColor(DivideColor<'a>),
// DivideStyle(DivideStyle),
// OutlineWidth(OutlineWidth<'a>),
// OutlineColor(OutlineColor<'a>),
// OutlineStyle(OutlineStyle),
// OutlineOffset(OutlineOffset<'a>),
// RingWidth(RingWidth<'a>),
// RingColor(RingColor<'a>),
// RingOffsetWidth(RingOffsetWidth<'a>),
// RingOffsetColor(RingOffsetColor<'a>),
// }
#[derive(Debug, PartialEq, Hash)]
pub enum Borders<'a> {
BorderRadius(BorderRadius<'a>),
BorderWidth(BorderWidth<'a>),
BorderColor(BorderColor<'a>),
BorderStyle(BorderStyle),
DivideWidth(DivideWidth<'a>),
DivideColor(DivideColor<'a>),
DivideStyle(DivideStyle),
OutlineWidth(OutlineWidth<'a>),
OutlineColor(OutlineColor<'a>),
OutlineStyle(OutlineStyle),
OutlineOffset(OutlineOffset<'a>),
RingWidth(RingWidth<'a>),
RingColor(RingColor<'a>),
RingOffsetWidth(RingOffsetWidth<'a>),
RingOffsetColor(RingOffsetColor<'a>),
}

#[derive(Debug, PartialEq, Hash)]
pub enum BorderRadius<'a> {
Around(&'a str),
Top(&'a str),
Right(&'a str),
Bottom(&'a str),
Left(&'a str),
TopLeft(&'a str),
TopRight(&'a str),
BottomRight(&'a str),
BottomLeft(&'a str),
}

#[derive(Debug, PartialEq, Hash)]
pub enum BorderColor<'a> {
Around(&'a str),
X(&'a str),
Y(&'a str),
Top(&'a str),
Right(&'a str),
Bottom(&'a str),
Left(&'a str),
}

#[derive(Debug, PartialEq, Hash)]
pub enum BorderStyle {
Solid,
Dashed,
Dotted,
Double,
Hidden,
None,
}

#[derive(Debug, PartialEq, Hash)]
pub enum BorderWidth<'a> {
Around(&'a str),
X(&'a str),
Y(&'a str),
Top(&'a str),
Right(&'a str),
Bottom(&'a str),
Left(&'a str),
}

#[derive(Debug, PartialEq, Hash)]
pub enum DivideWidth<'a> {
X(&'a str),
Y(&'a str),
ReverseX,
ReverseY,
}

#[derive(Debug, PartialEq, Hash)]
pub struct DivideColor<'a>(pub &'a str);

#[derive(Debug, PartialEq, Hash)]
pub enum DivideStyle {
Solid,
Dashed,
Dotted,
Double,
None,
}

#[derive(Debug, PartialEq, Hash)]
pub struct OutlineWidth<'a>(pub &'a str);

#[derive(Debug, PartialEq, Hash)]
pub struct OutlineColor<'a>(pub &'a str);

#[derive(Debug, PartialEq, Hash)]
pub enum OutlineStyle {
None,
Solid,
Dashed,
Dotted,
Double,
}

#[derive(Debug, PartialEq, Hash)]
pub struct OutlineOffset<'a>(pub &'a str);

#[derive(Debug, PartialEq, Hash)]
pub enum RingWidth<'a> {
Value(&'a str),
Inset,
}

#[derive(Debug, PartialEq, Hash)]
pub struct RingColor<'a>(pub &'a str);

#[derive(Debug, PartialEq, Hash)]
pub struct RingOffsetWidth<'a>(pub &'a str);

#[derive(Debug, PartialEq, Hash)]
pub struct RingOffsetColor<'a>(pub &'a str);

// pub fn borders<'a>(input: &'a str, config: &'a Config) -> IResult<&'a str, Borders<'a>> {
// todo!()
Expand Down
2 changes: 1 addition & 1 deletion railwind/src/class/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub use transforms::*;
pub use transitions_animation::*;
pub use typography::*;

use crate::{warning::WarningType, Config};
use crate::{config::Config, warning::WarningType};

#[derive(Debug, PartialEq, Hash)]
pub enum Class<'a> {
Expand Down
2 changes: 1 addition & 1 deletion railwind/src/class/spacing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use nom::{bytes::complete::tag, combinator::map};
use crate::class::utils::{keyword_value, neg_keyword_value};
use crate::class::Decl;
use crate::class::IntoDeclaration;
use crate::Config;
use crate::config::Config;

#[derive(Debug, PartialEq, Hash)]
pub enum Spacing<'a> {
Expand Down
Loading

0 comments on commit bfdf644

Please sign in to comment.