Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

12 support for string arrays #16

Merged
merged 7 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 9 additions & 21 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
[workspace]
workspace.resolver = "2"
members = ["twust-macro", "tailwind"]
members = ["twust", "twust_macro", "tailwind"]


[workspace.package]
name = "twust"
version = "1.0.5"
version = "1.0.6"
edition = "2021"
authors = ["Oyelowo Oyedayo"]
email = ["[email protected]"]
readme = "README.md"
documentation = "https://docs.rs/nom"
documentation = "https://docs.rs/twust"
# documentation = "https://codebreather.com/oyelowo"
repository = "https://github.com/Oyelowo/twust"
description = "Zero-config Static type-checker for Tailwind CSS"
license = "MIT/Apache-2.0"
categories = ["UI", "css", "tailwindcss", "web-programming"]
keywords = [
"tailwind",
"css",
"tailwindcss",
"frontend",
"ui",
"rust",
"web",
"twust",
]
keywords = ["tailwind", "css", "tailwindcss", "ui", "web"]


# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand All @@ -34,16 +26,12 @@ keywords = [


[workspace.dependencies]
twust = { path = "twust-macro" }
# tailwind = { path = "tailwind" }

twust = { path = "twust" }
twust_macro = { version = "1.0.6" }
# twust_macro = { path = "twust_macro" }
proc-macro2 = "1.0.69"
quote = "1.0.33"
syn = "2.0.38"
syn = { version = "2.0.38" }
nom = "7.1.3"
static_assertions = "1.1.0"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
regex = "1.10.0"
# tailwindcss-core = { git = "https://github.com/Oyelowo/tailwindcss.git", rev = "696810fd5a3d30ee8225913af268be1d2c9dbced" }
# tailwindcss-core = { git = "https://github.com/Oyelowo/tailwindcss/oxide/crates/core.git", rev = "696810fd5a3d30ee8225913af268be1d2c9dbced" }
1 change: 0 additions & 1 deletion tailwind/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ documentation.workspace = true
[dependencies]
twust = { workspace = true, features = ["daisyui"] }


serde = "1.0.188"
serde_json = "1.0.105"
35 changes: 35 additions & 0 deletions tailwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,38 @@ fn _happy_paths() {
tw!("h-full border-2 border-mana-53 border-opacity-60 rounded-lg overflow-hidden");
}
}

fn _happy_paths_list() {
fn main() {
let _classnames = tw![
"group-data-[selected=Right]:w-[30px]",
"group-aria-[main-page=false]/main:hidden",
"group-data-[main-page=false]/main:hidden",
"*:overflow-scroll",
"bg-taxvhiti bg-tahiti-500 bg-tahiti bg-midnight bg-red-50",
"bg-taxvhiti bg-tahiti-500 bg-tahiti bg-midnight bg-purple bg-red-50 bg-tahiti-800 border-s-tahiti-800",
"md:text-red-50 text-slate-50 text-purple text-tahiti-500",
"py-sm md:py-md tablet:py-sm lg:py-lg xl:py-xl",
"group",
"text-sm font-medium text-slate-300 group-hover:text-white",
"text-sm font-medium text-slate-500 group-hover:text-slate-300",
"hover:-translate-y-0.5 transition motion-reduce:hover:translate-y-0 motion-reduce:transition-none",
"motion-safe:hover:-translate-x-0.5 motion-safe:transition"
];
}
}

#[test]
fn test() {
let classes = tw!("group-data-[selected=Right]:w-[30px]");
assert_eq!(classes, "group-data-[selected=Right]:w-[30px]");

let classes = tw!("group-aria-[main-page=false]/main:hidden");
assert_eq!(classes, "group-aria-[main-page=false]/main:hidden");

let classes = tw!("group-data-[main-page=false]/main:hidden");
assert_eq!(classes, "group-data-[main-page=false]/main:hidden");

let classlist = tw!["group-data-[selected=Right]:w-[30px]", "group-aria-[main-page=false]/main:hidden", "group-data-[main-page=false]/main:hidden", "*:overflow-scroll", "bg-taxvhiti bg-tahiti-500 bg-tahiti bg-midnight bg-red-50", "bg-taxvhiti bg-tahiti-500 bg-tahiti bg-midnight bg-purple bg-red-50 bg-tahiti-800 border-s-tahiti-800", "md:text-red-50 text-slate-50 text-purple text-tahiti-500", "py-sm md:py-md tablet:py-sm lg:py-lg xl:py-xl", "group", "text-sm font-medium text-slate-300 group-hover:text-white", "text-sm font-medium text-slate-500 group-hover:text-slate-300", "hover:-translate-y-0.5 transition motion-reduce:hover:translate-y-0 motion-reduce:transition-none", "motion-safe:hover:-translate-x-0.5 motion-safe:transition"];
assert_eq!(classlist, "group-data-[selected=Right]:w-[30px] group-aria-[main-page=false]/main:hidden group-data-[main-page=false]/main:hidden *:overflow-scroll bg-taxvhiti bg-tahiti-500 bg-tahiti bg-midnight bg-red-50 bg-taxvhiti bg-tahiti-500 bg-tahiti bg-midnight bg-purple bg-red-50 bg-tahiti-800 border-s-tahiti-800 md:text-red-50 text-slate-50 text-purple text-tahiti-500 py-sm md:py-md tablet:py-sm lg:py-lg xl:py-xl group text-sm font-medium text-slate-300 group-hover:text-white text-sm font-medium text-slate-500 group-hover:text-slate-300 hover:-translate-y-0.5 transition motion-reduce:hover:translate-y-0 motion-reduce:transition-none motion-safe:hover:-translate-x-0.5 motion-safe:transition ");
}
21 changes: 21 additions & 0 deletions twust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "twust"
version = { workspace = true }
edition = { workspace = true }
authors = { workspace = true }
documentation = { workspace = true }
description = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
readme = { workspace = true }
keywords = { workspace = true }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
daisyui = []

[dependencies]
twust_macro = { workspace = true }


75 changes: 75 additions & 0 deletions twust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Author: Oyelowo Oyedayo
* Email: [email protected]
* Copyright (c) 2025 Oyelowo Oyedayo
* Licensed under the MIT license
*/

pub use twust_macro::tw as twust;
// // use twust_macro::xtw;
//
// #[macro_export]
// macro_rules! tw {
// // Case: Single string
// ($single:literal) => {
// $single
// };
// ($($class:literal),*) => {
// concat!($($class, " "),*)
// };
//
// ([$($class:expr),*]) => {
// concat!($($class, " "),*)
// };
// }
//
// fn main() {
// let _classnames_single = tw!("scroll-m-14 flex supports-grid:grid supports-[display:grid]:grid");
// let _classnames_array = tw!["scroll-m-14", "flex", "supports-grid:grid", "supports-[display:grid]:grid"];
// let _classnames_array2 = tw!(["scroll-m-14", "flex", "supports-grid:grid", "supports-[display:grid]:grid"]);
// // let _classnames_array2 = twx!(["scroll-m-14", "flex", "supports-grid:grid", "supports-[display:grid]:grid"]);
// // let _classnames_array2 = twx!(["scroll-m-14", "flex", "supports-grid:grid", "supports-[display:grid]:grid"]);
// }
//



/// Typechecks tailwindcss classnames at compile time.
///
/// ## Features:
/// - Supports **single string** literals (`tw!("class1 class2")`)
/// - Supports **multiple string arguments** (`tw!["class1", "class2"]`)
/// - Supports **arrays of strings** (`tw!(["class1", "class2"])`)
///
///
/// ## Example Usage
///
/// ```rust, ignore
/// use twust::tw;
///
/// let single_class = tw!("scroll-m-14 flex supports-grid:grid supports-[display:grid]:grid");
/// let multiple_classes = tw!["scroll-m-14", "flex", "supports-grid:grid", "supports-[display:grid]:grid"];
/// let array_classes = tw!(["scroll-m-14", "flex", "supports-grid:grid", "supports-[display:grid]:grid"]);
///
/// assert_eq!(single_class, "scroll-m-14 flex supports-grid:grid supports-[display:grid]:grid");
/// assert_eq!(multiple_classes, "scroll-m-14 flex supports-grid:grid supports-[display:grid]:grid");
/// assert_eq!(array_classes, "scroll-m-14 flex supports-grid:grid supports-[display:grid]:grid");
/// ```
///
/// ## Notes
/// - The macro supports **both** `tw!(...)` and `tw![...]` syntax.
/// - It ensures at compile time that only string literals are used for class names.
#[macro_export]
macro_rules! tw {
($single:literal) => {
$single
};

($($class:literal),*) => {
concat!($($class, " "),*)
};

([$($class:expr),*]) => {
concat!($($class, " "),*)
};
}
16 changes: 5 additions & 11 deletions twust-macro/Cargo.toml → twust_macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
[package]
name = "twust"
name = "twust_macro"
version = { workspace = true }
edition = { workspace = true }
authors = { workspace = true }
# description = { workspace = true }
documentation = { workspace = true }
license = { workspace = true }
repository = "https://github.com/Oyelowo/twust"
description = "Static checker for tailwindcss class names in rust for rust"
readme = "../README.md"
keywords = ["tailwindcss", "tailwind", "css", "leptos", "yew"]
repository = { workspace = true }
description = { workspace = true }
readme = { workspace = true }
keywords = { workspace = true }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
daisyui = []

# workspace = "."

[dependencies]
syn = { workspace = true }
proc-macro2 = { workspace = true }
quote = { workspace = true }
nom = { workspace = true }
static_assertions = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
regex = { workspace = true }
# tailwindcss-core = { workspace = true }


[lib]
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
41 changes: 38 additions & 3 deletions twust-macro/src/lib.rs → twust_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
* Licensed under the MIT license
*/

use std::collections::HashSet;

use nom::{
branch::alt,
bytes::complete::{tag, take_until, take_while1},
Expand All @@ -17,6 +15,7 @@ use nom::{
sequence::{preceded, tuple},
IResult,
};
use std::collections::HashSet;
use syn::{parse_macro_input, LitStr};
mod config;
mod plugins;
Expand All @@ -29,7 +28,6 @@ use tailwind::{
use config::{get_classes, noconfig::UNCONFIGURABLE, read_tailwind_config};
use proc_macro::TokenStream;
use tailwind::signable::SIGNABLES;
// use tailwindcss_core::parser::{Extractor, ExtractorOptions};

fn setup(input: &LitStr) -> Result<(Vec<String>, Vec<String>), TokenStream> {
let config = &(match read_tailwind_config() {
Expand Down Expand Up @@ -766,3 +764,40 @@ pub fn tw(raw_input: TokenStream) -> TokenStream {
}
.into()
}

// // Requires featues = full. Dont need it, can just use macrorules
// #[proc_macro]
// pub fn tws(raw_input: TokenStream) -> TokenStream {
// let input = parse_macro_input!(raw_input as Expr);
//
// let mut all_classnames = Vec::new();
//
// match input {
// Expr::Array(array) => {
// for expr in array.elems.iter() {
// if let Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(lit_str), .. }) = expr {
// all_classnames.push(lit_str.value());
// } else {
// return syn::Error::new_spanned(expr, "Expected string literals in the array")
// .to_compile_error()
// .into();
// }
// }
// }
// Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(lit_str), .. }) => {
// all_classnames.push(lit_str.value());
// }
// _ => {
// return syn::Error::new_spanned(input, "Expected a string literal or an array of string literals")
// .to_compile_error()
// .into();
// }
// }
//
// let concatenated = all_classnames.join(" ");
//
// quote::quote! {
// #concatenated
// }
// .into()
// }
File renamed without changes.
File renamed without changes.
File renamed without changes.