Skip to content

Commit

Permalink
Move aligned_column, aligned_row macros to kas_widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
dhardy committed Feb 13, 2025
1 parent 2307b46 commit 9175888
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 256 deletions.
76 changes: 64 additions & 12 deletions crates/kas-macros/src/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ use syn::parse::{Error, Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::Comma;
use syn::{braced, parenthesized};
use syn::{braced, bracketed, parenthesized};
use syn::{Expr, Ident, LitInt, LitStr, Token};

#[allow(non_camel_case_types)]
mod kw {
syn::custom_keyword!(align);
syn::custom_keyword!(pack);
syn::custom_keyword!(aligned_column);
syn::custom_keyword!(aligned_row);
syn::custom_keyword!(column);
syn::custom_keyword!(row);
}

#[derive(Default)]
Expand Down Expand Up @@ -212,33 +216,41 @@ impl Parse for Collection {
}

impl Parse for CellCollection {
fn parse(inner: ParseStream) -> Result<Self> {
fn parse(input: ParseStream) -> Result<Self> {
if input.peek(kw::aligned_column) {
let _: kw::aligned_column = input.parse()?;
return Self::parse_aligned::<kw::row>(input, false);
} else if input.peek(kw::aligned_row) {
let _: kw::aligned_row = input.parse()?;
return Self::parse_aligned::<kw::column>(input, true);
}

let mut gen = NameGenerator::default();

let mut cells = vec![];
let mut items = vec![];
while !inner.is_empty() {
cells.push(inner.parse()?);
let _: Token![=>] = inner.parse()?;
while !input.is_empty() {
cells.push(input.parse()?);
let _: Token![=>] = input.parse()?;

let item;
let require_comma;
if inner.peek(syn::token::Brace) {
let inner2;
let _ = braced!(inner2 in inner);
item = Item::parse(&inner2, &mut gen)?;
if input.peek(syn::token::Brace) {
let inner;
let _ = braced!(inner in input);
item = Item::parse(&inner, &mut gen)?;
require_comma = false;
} else {
item = Item::parse(inner, &mut gen)?;
item = Item::parse(input, &mut gen)?;
require_comma = true;
}
items.push(item);

if inner.is_empty() {
if input.is_empty() {
break;
}

if let Err(e) = inner.parse::<Token![,]>() {
if let Err(e) = input.parse::<Token![,]>() {
if require_comma {
return Err(e);
}
Expand All @@ -249,6 +261,46 @@ impl Parse for CellCollection {
}
}

impl CellCollection {
fn parse_aligned<Kw: Parse>(input: ParseStream, transmute: bool) -> Result<Self> {
let mut gen = NameGenerator::default();
let mut cells = vec![];
let mut items = vec![];

let mut row = 0;
while !input.is_empty() {
let _: Kw = input.parse()?;
let _: Token![!] = input.parse()?;

let inner;
let _ = bracketed!(inner in input);
let mut col = 0;
while !inner.is_empty() {
let (mut a, mut b) = (col, row);
if transmute {
(a, b) = (b, a);
}
cells.push(CellInfo::new(a, b));
items.push(Item::parse(&inner, &mut gen)?);

if inner.is_empty() {
break;
}
let _: Token![,] = inner.parse()?;
col += 1;
}

if input.is_empty() {
break;
}
let _: Token![,] = input.parse()?;
row += 1;
}

Ok(CellCollection(cells, Collection(items)))
}
}

impl Collection {
pub fn impl_parts(&self) -> (Toks, Toks, Toks, Toks, Toks) {
let mut data_ty = None;
Expand Down
63 changes: 3 additions & 60 deletions crates/kas-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ pub fn impl_scope(input: TokenStream) -> TokenStream {
/// implementation of `Tile::nav_next`, with a couple of exceptions
/// (where macro-time analysis is insufficient to implement this method).
///
/// > [_Column_], [_Row_], [_List_] [_AlignedColumn_](macro@aligned_column), [_AlignedRow_](macro@aligned_row), [_Grid_], [_Float_], [_Frame_] :\
/// > [_Column_], [_Row_], [_List_] [_AlignedColumn_], [_AlignedRow_], [_Grid_], [_Float_], [_Frame_] :\
/// > &nbsp;&nbsp; These stand-alone macros are explicitly supported in this position.\
///
/// > _Single_ :\
Expand Down Expand Up @@ -323,6 +323,8 @@ pub fn impl_scope(input: TokenStream) -> TokenStream {
/// [_Float_]: https://docs.rs/kas-widgets/latest/kas_widgets/macro.float.html
/// [_Frame_]: https://docs.rs/kas-widgets/latest/kas_widgets/macro.frame.html
/// [_Grid_]: https://docs.rs/kas-widgets/latest/kas_widgets/macro.grid.html
/// [_AlignedColumn_]: https://docs.rs/kas-widgets/latest/kas_widgets/macro.aligned_column.html
/// [_AlignedRow_]: https://docs.rs/kas-widgets/latest/kas_widgets/macro.aligned_row.html
#[proc_macro_attribute]
#[proc_macro_error]
pub fn widget(_: TokenStream, item: TokenStream) -> TokenStream {
Expand Down Expand Up @@ -435,65 +437,6 @@ pub fn widget_set_rect(input: TokenStream) -> TokenStream {
input.into_token_stream().into()
}

trait ExpandLayout {
fn expand_layout(self, name: &str) -> TokenStream;
}
impl ExpandLayout for make_layout::Tree {
fn expand_layout(self, name: &str) -> TokenStream {
match self.expand_as_widget(name) {
Ok(toks) => toks.into(),
Err(err) => {
emit_call_site_error!(err);
TokenStream::default()
}
}
}
}

/// Define a [`Grid`] as a sequence of rows
///
/// This is just special convenience syntax for defining a [`Grid`]. See also
/// [`grid!`] documentation.
///
/// # Example
///
/// ```ignore
/// let my_widget = kas::aligned_column! [
/// row!["one", "two"],
/// row!["three", "four"],
/// ];
/// ```
///
/// [`[Grid`]: https://docs.rs/kas/latest/kas/widgets/struct.Grid.html
/// [`grid!`]: https://docs.rs/kas-widgets/latest/kas_widgets/macro.grid.html
#[proc_macro_error]
#[proc_macro]
pub fn aligned_column(input: TokenStream) -> TokenStream {
parse_macro_input!(input with make_layout::Tree::aligned_column).expand_layout("_AlignedColumn")
}

/// Define a [`Grid`] as a sequence of columns
///
/// This is just special convenience syntax for defining a [`Grid`]. See also
/// [`grid!`] documentation.
///
/// # Example
///
/// ```ignore
/// let my_widget = kas::aligned_row! [
/// column!["one", "two"],
/// column!["three", "four"],
/// ];
/// ```
///
/// [`[Grid`]: https://docs.rs/kas/latest/kas/widgets/struct.Grid.html
/// [`grid!`]: https://docs.rs/kas-widgets/latest/kas_widgets/macro.grid.html
#[proc_macro_error]
#[proc_macro]
pub fn aligned_row(input: TokenStream) -> TokenStream {
parse_macro_input!(input with make_layout::Tree::aligned_row).expand_layout("_AlignedRow")
}

/// Generate an anonymous struct which implements [`kas::Collection`]
///
/// # Syntax
Expand Down
Loading

0 comments on commit 9175888

Please sign in to comment.