Skip to content

Commit

Permalink
Refactor 3 invokable types to implement a trait, which allows lookup …
Browse files Browse the repository at this point in the history
…to be refactored

- They now implement an Invokable trait which can be extended to improve shared functionality
- This allowed refactoring of method and signal lookup to use a common lookup function
  • Loading branch information
BenFordTytherington committed Aug 30, 2024
1 parent 02b67fe commit 2a43203
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 21 deletions.
30 changes: 12 additions & 18 deletions crates/cxx-qt-gen/src/generator/structuring/qobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::naming::Name;
use crate::parser::inherit::ParsedInheritedMethod;
use crate::parser::method::ParsedMethod;
use crate::parser::signals::ParsedSignal;
use crate::parser::{qenum::ParsedQEnum, qobject::ParsedQObject};
use crate::parser::{qenum::ParsedQEnum, qobject::ParsedQObject, Invokable};
use proc_macro2::Ident;
use syn::{Error, Result};

Expand All @@ -21,6 +21,14 @@ pub struct StructuredQObject<'a> {
pub signals: Vec<&'a ParsedSignal>,
}

fn lookup(invokables: &Vec<impl Invokable>, id: &Ident) -> Option<Name> {
invokables
.iter()
.map(|invokable| invokable.name())
.find(|name| name.rust_unqualified() == id)
.cloned()
}

impl<'a> StructuredQObject<'a> {
pub fn has_qobject_name(&self, ident: &Ident) -> bool {
self.declaration.name.rust_unqualified() == ident
Expand All @@ -39,28 +47,14 @@ impl<'a> StructuredQObject<'a> {

/// Returns the name of the method with the provided Rust ident if it exists, or an error
pub fn method_lookup(&self, id: &Ident) -> Result<Name> {
self.methods
.iter()
.map(|method| &method.name)
.find(|name| name.rust_unqualified() == id)
.cloned()
.or_else(|| {
self.inherited_methods
.iter()
.map(|inherited_method| &inherited_method.name)
.find(|name| name.rust_unqualified() == id)
.cloned()
})
lookup(&self.methods, id)
.or_else(|| lookup(&self.inherited_methods, id)) // fallback to searching inherited methods
.ok_or_else(|| Error::new_spanned(id, format!("Method with name '{id}' not found!")))
}

/// Returns the name of the signal with the provided Rust ident if it exists, or an error
pub fn signal_lookup(&self, id: &Ident) -> Result<Name> {
self.signals
.iter()
.map(|signal| &signal.name)
.find(|name| name.rust_unqualified() == id)
.cloned()
lookup(&self.signals, id)
.ok_or_else(|| Error::new_spanned(id, format!("Signal with name '{id}' not found!")))
}

Expand Down
10 changes: 9 additions & 1 deletion crates/cxx-qt-gen/src/parser/inherit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use crate::parser::{check_safety, extract_common_fields, separate_docs, InvokableFields};
use crate::parser::{
check_safety, extract_common_fields, separate_docs, Invokable, InvokableFields,
};
use crate::{
naming::Name,
parser::parameter::ParsedFunctionParameter,
Expand All @@ -30,6 +32,12 @@ pub struct ParsedInheritedMethod {
pub docs: Vec<Attribute>,
}

impl Invokable for &ParsedInheritedMethod {
fn name(&self) -> &Name {
&self.name
}
}

impl ParsedInheritedMethod {
pub fn parse(mut method: ForeignItemFn, safety: Safety) -> Result<Self> {
check_safety(&method, &safety)?;
Expand Down
10 changes: 9 additions & 1 deletion crates/cxx-qt-gen/src/parser/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use crate::{
use std::collections::HashSet;
use syn::{Attribute, Error, ForeignItemFn, Ident, Result};

use crate::parser::{check_safety, extract_common_fields, separate_docs, InvokableFields};
use crate::parser::{
check_safety, extract_common_fields, separate_docs, Invokable, InvokableFields,
};
#[cfg(test)]
use quote::format_ident;

Expand Down Expand Up @@ -55,6 +57,12 @@ pub struct ParsedMethod {
pub docs: Vec<Attribute>,
}

impl Invokable for &ParsedMethod {
fn name(&self) -> &Name {
&self.name
}
}

impl ParsedMethod {
pub fn parse(mut method: ForeignItemFn, safety: Safety) -> Result<Self> {
check_safety(&method, &safety)?;
Expand Down
5 changes: 5 additions & 0 deletions crates/cxx-qt-gen/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod qnamespace;
pub mod qobject;
pub mod signals;

use crate::naming::Name;
use crate::parser::parameter::ParsedFunctionParameter;
use crate::syntax::safety::Safety;
use crate::syntax::{foreignmod, types};
Expand Down Expand Up @@ -42,6 +43,10 @@ fn check_safety(method: &ForeignItemFn, safety: &Safety) -> Result<()> {
}
}

pub trait Invokable {
fn name(self: &Self) -> &Name;
}

/// Struct with common fields between Invokable types.
/// These types are ParsedSignal, ParsedMethod and ParsedInheritedMethod
pub struct InvokableFields {
Expand Down
10 changes: 9 additions & 1 deletion crates/cxx-qt-gen/src/parser/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use crate::{
};
use syn::{spanned::Spanned, Attribute, Error, ForeignItemFn, Ident, Result, Visibility};

use crate::parser::{check_safety, extract_common_fields, separate_docs, InvokableFields};
use crate::parser::{
check_safety, extract_common_fields, separate_docs, Invokable, InvokableFields,
};
#[cfg(test)]
use quote::format_ident;

Expand All @@ -37,6 +39,12 @@ pub struct ParsedSignal {
pub docs: Vec<Attribute>,
}

impl Invokable for &ParsedSignal {
fn name(&self) -> &Name {
&self.name
}
}

impl ParsedSignal {
/// Builds a signal from a given property method
pub fn from_property_method(
Expand Down

0 comments on commit 2a43203

Please sign in to comment.