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

autoimpl; revise widget macros #258

Merged
merged 33 commits into from
Nov 29, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8df442d
Remove outdated TODO
dhardy Nov 4, 2021
5b360e3
Replace derive(Widget) with function-like macro
dhardy Nov 9, 2021
3dc8b0b
Move impls into widget! macro
dhardy Nov 10, 2021
4a53a0b
Move handling for impl on Self up
dhardy Nov 10, 2021
ee0ee6f
Update make_widget! to use impl Self syntax
dhardy Nov 10, 2021
db0c5bb
widget! macro: discover whether to derive WidgetChildren
dhardy Nov 10, 2021
dbf4833
widget! macro: discover whether to derive WidgetConfig
dhardy Nov 10, 2021
9a52612
widget! macro: discover whether to derive Handler and SendEvent
dhardy Nov 10, 2021
f3ba3a3
Remove handler type substitutions: unused and over-complex
dhardy Nov 10, 2021
188dede
Remove support for multiple handler impls: unused
dhardy Nov 10, 2021
0adb8a6
make_widget: simplify extra bounds
dhardy Nov 10, 2021
c6b14b1
Remove support for #[handler(generics = ...)]
dhardy Nov 10, 2021
a179288
kas_macros: move widget and make_widget impls to sub-modules
dhardy Nov 11, 2021
6377190
New autoimpl macro (only supports Debug)
dhardy Nov 11, 2021
04f7725
Use #[autoimpl(Debug)]
dhardy Nov 11, 2021
cd26bd3
autoimpl: support Clone
dhardy Nov 11, 2021
491544d
autoimpl: support Deref, DerefMut
dhardy Nov 11, 2021
0abcc6a
Remove widget_derive support for Deref, DerefMut
dhardy Nov 11, 2021
0b19d7d
autoimpl: on and skip are mutually exclusive
dhardy Nov 13, 2021
ac84441
autoimpl: revise implementation, reporting more errors during parsing
dhardy Nov 13, 2021
ee4ceac
autoimpl: support each class trait
dhardy Nov 13, 2021
4745922
autoimpl: support "where T: trait" syntax
dhardy Nov 24, 2021
761b8a2
autoimpl: support deriving class_traits
dhardy Nov 24, 2021
6c39ea5
widget_derive: remove support for class_traits
dhardy Nov 24, 2021
2fd058e
Move more class trait impls to autoimpl
dhardy Nov 24, 2021
71be81a
Replace #[widget_derive] with #[widget(derive=FIELD)]
dhardy Nov 25, 2021
d8fd49c
Update widget and autoimpl macro doc; fix examples
dhardy Nov 28, 2021
a4cd76a
Fix mandlebrot example
dhardy Nov 28, 2021
4f9049a
autoimpl: use paths on bounds inferred via X: trait
dhardy Nov 28, 2021
6cd00f4
Clippy fixes
dhardy Nov 28, 2021
97f23b2
autoimpl before derive
dhardy Nov 28, 2021
eb7c6f5
Apply required bounds on GATs
dhardy Nov 29, 2021
cb6eb56
autoimpl: support Default
dhardy Nov 29, 2021
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
Prev Previous commit
Next Next commit
Update make_widget! to use impl Self syntax
  • Loading branch information
dhardy committed Nov 10, 2021
commit ee0ee6f8f989c7501ae824490896095041d15845
29 changes: 8 additions & 21 deletions crates/kas-macros/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,11 +328,14 @@ fn parse_impl(in_ident: Option<&Ident>, input: ParseStream) -> Result<ItemImpl>
{
abort!(
self_ty.span(),
format!("expected `Self` or `{0}` or `{0}<...>`", ident)
format!(
"expected `Self` or `{0}` or `{0}<...>` or `Trait for Self`, etc",
ident
)
);
}
} else {
abort!(self_ty.span(), "expected `Self`");
abort!(self_ty.span(), "expected `Self` or `Trait for Self`");
}
}

Expand Down Expand Up @@ -1187,7 +1190,7 @@ pub struct MakeWidget {
// child widgets and data fields
pub fields: Vec<WidgetField>,
// impl blocks on the widget
pub impls: Vec<(Option<TypePath>, Vec<syn::ImplItem>)>,
pub impls: Vec<ItemImpl>,
}

impl Parse for MakeWidget {
Expand Down Expand Up @@ -1229,25 +1232,9 @@ impl Parse for MakeWidget {
let _: Comma = content.parse()?;
}

let mut impls = vec![];
let mut impls = Vec::new();
while !input.is_empty() {
let _: Impl = input.parse()?;

let target = if input.peek(Brace) {
None
} else {
Some(input.parse::<TypePath>()?)
};

let content;
let _ = braced!(content in input);
let mut methods = vec![];

while !content.is_empty() {
methods.push(content.parse::<syn::ImplItem>()?);
}

impls.push((target, methods));
impls.push(parse_impl(None, input)?);
}

Ok(MakeWidget {
Expand Down
65 changes: 27 additions & 38 deletions crates/kas-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,7 @@ pub fn widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let mut find_handler_ty_buf: Vec<(Ident, Type)> = vec![];
// find type of handler's message; return None on error
let mut find_handler_ty = |handler: &Ident,
impls: &Vec<(Option<TypePath>, Vec<syn::ImplItem>)>|
-> Option<Type> {
let mut find_handler_ty = |handler: &Ident, impls: &Vec<ItemImpl>| -> Option<Type> {
// check the buffer in case we did this already
for (ident, ty) in &find_handler_ty_buf {
if ident == handler {
Expand All @@ -663,7 +661,10 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let mut x: Option<(Ident, Type)> = None;

for impl_block in impls {
for f in &impl_block.1 {
if impl_block.trait_.is_some() {
continue;
}
for f in &impl_block.items {
match f {
syn::ImplItem::Method(syn::ImplItemMethod { sig, .. })
if sig.ident == *handler =>
Expand Down Expand Up @@ -726,27 +727,27 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let mut send = true;
let mut msg = None;
let msg_ident: Ident = parse_quote! { Msg };
for (name, body) in &args.impls {
if name == &Some(parse_quote! { Handler })
|| name == &Some(parse_quote! { ::kas::Handler })
{
handle = false;

for item in body {
match item {
syn::ImplItem::Type(syn::ImplItemType {
ref ident, ref ty, ..
}) if *ident == msg_ident => {
msg = Some(ty.clone());
continue;
for impl_block in &args.impls {
if let Some((_, ref name, _)) = impl_block.trait_ {
if *name == parse_quote! { Handler } || *name == parse_quote! { ::kas::Handler } {
handle = false;

for item in &impl_block.items {
match item {
syn::ImplItem::Type(syn::ImplItemType {
ref ident, ref ty, ..
}) if *ident == msg_ident => {
msg = Some(ty.clone());
continue;
}
_ => (),
}
_ => (),
}
} else if *name == parse_quote! { SendEvent }
|| *name == parse_quote! { ::kas::SendEvent }
{
send = false;
}
} else if name == &Some(parse_quote! { SendEvent })
|| name == &Some(parse_quote! { ::kas::SendEvent })
{
send = false;
}
}

Expand Down Expand Up @@ -855,24 +856,12 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
});
}

let (impl_generics, ty_generics, where_clause) = args.generics.split_for_impl();
let (impl_generics, _, where_clause) = args.generics.split_for_impl();

let mut impls = quote! {};

for impl_block in args.impls {
let mut contents = TokenStream::new();
for method in impl_block.1 {
contents.append_all(std::iter::once(method));
}
let target = if let Some(t) = impl_block.0 {
quote! { #t for }
} else {
quote! {}
};
impls.append_all(quote! {
impl #impl_generics #target AnonWidget #ty_generics #where_clause {
#contents
}
#impl_block
});
}

Expand All @@ -886,9 +875,9 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
struct AnonWidget #impl_generics #where_clause {
#field_toks
}
}

#impls
#impls
}

AnonWidget {
#field_val_toks
Expand Down
4 changes: 2 additions & 2 deletions examples/calculator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget(col = 2, row = 4)]
_ = TextButton::new_msg("&.", Key::Char('.')),
}
impl kas::WidgetConfig {
impl kas::WidgetConfig for Self {
fn configure(&mut self, mgr: &mut Manager) {
// Enable key bindings without Alt held:
mgr.enable_alt_bypass(true);
Expand All @@ -85,7 +85,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget(use_msg = handle_button)] buttons -> Key = buttons,
calc: Calculator = Calculator::new(),
}
impl {
impl Self {
fn handle_button(&mut self, mgr: &mut Manager, msg: Key) {
if self.calc.handle(msg) {
*mgr |= self.display.set_string(self.calc.display());
Expand Down
2 changes: 1 addition & 1 deletion examples/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn main() -> Result<(), kas::shell::Error> {
],
count: i32 = 0,
}
impl {
impl Self {
fn handle_button(&mut self, mgr: &mut Manager, incr: i32) {
self.count += incr;
*mgr |= self.display.set_string(self.count.to_string());
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ fn main() -> Result<(), kas::shell::Error> {
struct {
#[widget(use_msg = handler)] _ = widgets,
}
impl {
impl Self {
fn handler(&mut self, _: &mut Manager, item: Item) {
match item {
Item::White => BACKGROUND.with(|b| b.set(Rgba::WHITE)),
Expand Down
4 changes: 2 additions & 2 deletions examples/data-list-view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget] _ = TextButton::new_msg("↓↑", Control::Dir),
n: usize = 3,
}
impl {
impl Self {
fn activate(&mut self, _: &mut Manager, n: usize) -> Control {
self.n = n;
Control::Set(n)
Expand Down Expand Up @@ -253,7 +253,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget(use_msg = set_radio)] list: ScrollBars<MyList> =
ScrollBars::new(list).with_bars(false, true),
}
impl {
impl Self {
fn control(&mut self, mgr: &mut Manager, control: Control) {
match control {
Control::Set(len) => {
Expand Down
4 changes: 2 additions & 2 deletions examples/data-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget] _ = TextButton::new_msg("↓↑", Control::Dir),
n: usize = 3,
}
impl {
impl Self {
fn activate(&mut self, _: &mut Manager, n: usize) -> Control {
self.n = n;
Control::Set(n)
Expand Down Expand Up @@ -154,7 +154,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget] _ = Filler::maximize(),
active: usize = 0,
}
impl {
impl Self {
fn control(&mut self, mgr: &mut Manager, control: Control) {
match control {
Control::Set(len) => {
Expand Down
2 changes: 1 addition & 1 deletion examples/filter-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fn main() -> Result<(), kas::shell::Error> {
>> =
ScrollBars::new(FilterListView::new(data, filter)),
}
impl {
impl Self {
fn set_selection_mode(&mut self, mgr: &mut Manager, mode: SelectionMode) {
*mgr |= self.list.set_selection_mode(mode);
}
Expand Down
8 changes: 4 additions & 4 deletions examples/gallery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget(use_msg = edit)] edit = TextButton::new_msg("&Edit", ()),
future: Option<Future<Option<String>>> = None,
}
impl {
impl Self {
fn edit(&mut self, mgr: &mut Manager, _: ()) {
if self.future.is_none() {
let text = self.label.get_string();
Expand All @@ -192,7 +192,7 @@ fn main() -> Result<(), kas::shell::Error> {
}
}
}
impl Handler {
impl Handler for Self {
type Msg = VoidMsg;
fn handle(&mut self, mgr: &mut Manager, event: Event) -> Response<Self::Msg> {
match event {
Expand Down Expand Up @@ -267,7 +267,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget(row=12, col=0)] _ = Label::new("Child window"),
#[widget(row=12, col=1)] _ = popup_edit_box,
}
impl {
impl Self {
fn handle_slider(&mut self, _: &mut Manager, msg: i32) -> Item {
Item::Slider(msg)
}
Expand Down Expand Up @@ -300,7 +300,7 @@ fn main() -> Result<(), kas::shell::Error> {
for<W: Widget<Msg = Item>> ScrollBarRegion<W> =
ScrollBarRegion::new(widgets),
}
impl {
impl Self {
fn menu(&mut self, mgr: &mut Manager, msg: Menu) {
match msg {
Menu::Theme(name) => {
Expand Down
2 changes: 1 addition & 1 deletion examples/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ It also supports lists:
ScrollBarRegion::new(Label::new(Markdown::new(doc)?)),
#[widget(row=1, col=1, use_msg=update)] _ = TextButton::new_msg("&Update", ()),
}
impl {
impl Self {
fn update(&mut self, mgr: &mut Manager, _: ()) {
let text = match Markdown::new(self.editor.get_str()) {
Ok(text) => text,
Expand Down
2 changes: 1 addition & 1 deletion examples/splitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn main() -> Result<(), kas::shell::Error> {
#[widget(use_msg = handle_button)] buttons -> Message = buttons,
#[widget] panes: RowSplitter<EditField> = panes,
}
impl {
impl Self {
fn handle_button(&mut self, mgr: &mut Manager, msg: Message) {
match msg {
Message::Decr => {
Expand Down
6 changes: 3 additions & 3 deletions examples/stopwatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn make_window() -> Box<dyn kas::Window> {
saved: Duration = Duration::default(),
start: Option<Instant> = None,
}
impl {
impl Self {
fn reset(&mut self, mgr: &mut Manager, _: ()) {
self.saved = Duration::default();
self.start = None;
Expand All @@ -43,12 +43,12 @@ fn make_window() -> Box<dyn kas::Window> {
}
}
}
impl kas::WidgetConfig {
impl kas::WidgetConfig for Self {
fn configure(&mut self, mgr: &mut Manager) {
mgr.enable_alt_bypass(true);
}
}
impl Handler {
impl Handler for Self {
type Msg = VoidMsg;
fn handle(&mut self, mgr: &mut Manager, event: Event) -> Response<VoidMsg> {
match event {
Expand Down
2 changes: 1 addition & 1 deletion examples/sync-counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn main() -> Result<(), kas::shell::Error> {
TextButton::new_msg("+", 1),
],
}
impl {
impl Self {
fn update(&mut self, mgr: &mut Manager, msg: i32) {
self.counter.update_value(mgr, |v| v + msg);
}
Expand Down