diff --git a/src/configuration.rs b/src/configuration.rs index c1289de..a2ce9cd 100644 --- a/src/configuration.rs +++ b/src/configuration.rs @@ -120,7 +120,7 @@ impl ConfigPrivate for Config { ops.insert(p.type_name().into()); } } - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { ops.insert("quintptr".into()); } } @@ -129,7 +129,7 @@ impl ConfigPrivate for Config { fn has_list_or_tree(&self) -> bool { self.objects .values() - .any(|o| o.object_type == ObjectType::List || o.object_type == ObjectType::Tree) + .any(|o| o.object_type.is_model()) } } @@ -193,9 +193,35 @@ pub struct Rust { pub interface_module: String, } +impl ObjectType { + pub fn is_object(&self) -> bool { + match self { + ObjectType::Object | ObjectType::Widget => true, + _ => false, + } + } + + pub fn is_model(&self) -> bool {!self.is_object()} + + pub fn is_list(&self) -> bool { + match self { + ObjectType::List => true, + _ => false + } + } + + pub fn is_tree(&self) -> bool { + match self { + ObjectType::Tree => true, + _ => false + } + } +} + #[derive(Deserialize, Clone, Copy, PartialEq)] pub enum ObjectType { Object, + Widget, List, Tree, } diff --git a/src/cpp.rs b/src/cpp.rs index f174261..3ca2bd6 100644 --- a/src/cpp.rs +++ b/src/cpp.rs @@ -25,17 +25,24 @@ fn write_property(name: &str) -> String { } fn base_type(o: &Object) -> (&str, bool) { - let model = o.object_type != ObjectType::Object; - let name = if o.base_class != "" { &o.base_class - } else if o.object_type == ObjectType::Object { - "QAbstractItemModel" } else { - "QObject" + match o.object_type { + ObjectType::Widget => "QWidget", + ObjectType::Object => "QObject", + _ => "QAbstractItemModel", + } }; - (name, model) + (name, o.object_type.is_model()) +} + +fn parent_type(o: &Object) -> &str { + match o.object_type { + ObjectType::Widget => "QWidget", + _ => "QObject", + } } fn model_is_writable(o: &Object) -> bool { @@ -80,7 +87,7 @@ fn write_header_item_model(h: &mut Vec, o: &Object) -> Result<()> { } else { r.clone() }; - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!(h, " Q_INVOKABLE {} {}(int row) const;", r, name)?; if ip.write { writeln!( @@ -175,11 +182,12 @@ private:" } writeln!( h, - " explicit {}(bool owned, QObject *parent); + " explicit {}(bool owned, {1} *parent); public: - explicit {0}(QObject *parent = nullptr); + explicit {0}({1} *parent = nullptr); ~{0}();", - o.name + o.name, + parent_type(o) )?; for (name, p) in &o.properties { if p.is_object() { @@ -361,7 +369,7 @@ fn connect(w: &mut Vec, d: &str, o: &Object, conf: &Config) -> Result<()> { connect(w, &format!("{}->m_{}", d, name), object, conf)?; } } - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!( w, " connect({}, &{1}::newDataReady, {0}, [this](const QModelIndex& i) {{ @@ -377,10 +385,11 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { let lcname = snake_case(&o.name); writeln!( w, - "{}::{0}(bool /*owned*/, QObject *parent): - {}(parent),", + "{1}::{0}(bool /*owned*/, {2} *parent): + {1}(parent),", o.name, - base_type(o).0 + base_type(o).0, + parent_type(o) )?; initialize_members_zero(w, o)?; writeln!( @@ -389,17 +398,18 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { m_ownsPrivate(false) {{" )?; - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!(w, " initHeaderData();")?; } writeln!( w, "}} -{}::{0}(QObject *parent): - {}(parent),", +{1}::{0}({2} *parent): + {1}(parent),", o.name, - base_type(o).0 + base_type(o).0, + parent_type(o) )?; initialize_members_zero(w, o)?; write!(w, " m_d({}_new(this", lcname)?; @@ -412,7 +422,7 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { )?; initialize_members(w, "", o, conf)?; connect(w, "this", o, conf)?; - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!(w, " initHeaderData();")?; } writeln!( @@ -426,7 +436,7 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { }}", o.name, lcname )?; - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!(w, "void {}::initHeaderData() {{", o.name)?; for col in 0..o.column_count() { for (name, ip) in &o.item_properties { @@ -632,7 +642,7 @@ fn write_model_getter_setter( // getter let mut r = property_type(ip); - if o.object_type == ObjectType::List { + if o.object_type.is_list() { idx = ", row"; writeln!(w, "{} {}::{}(int row) const\n{{", r, o.name, name)?; } else { @@ -692,7 +702,7 @@ fn write_model_getter_setter( if r == "QVariant" || ip.is_complex() { r = format!("const {}&", r); } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { idx = ", row"; writeln!( w, @@ -763,7 +773,7 @@ fn write_model_getter_setter( if ip.optional { writeln!(w, " }}")?; } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!( w, " if (set) {{ @@ -790,7 +800,7 @@ fn write_model_getter_setter( fn write_cpp_model(w: &mut Vec, o: &Object) -> Result<()> { let lcname = snake_case(&o.name); - let (index_decl, index) = if o.object_type == ObjectType::Tree { + let (index_decl, index) = if o.object_type.is_tree() { (", quintptr", ", index.internalId()") } else { (", int", ", index.row()") @@ -840,7 +850,7 @@ fn write_cpp_model(w: &mut Vec, o: &Object) -> Result<()> { lcname, o.name )?; - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!( w, " @@ -1060,7 +1070,7 @@ Qt::ItemFlags {0}::flags(const QModelIndex &i) const writeln!(w, " case Qt::{}:", role_name(role))?; } writeln!(w, " case Qt::UserRole + {}:", i)?; - let ii = if o.object_type == ObjectType::List { + let ii = if o.object_type.is_list() { ".row()" } else { "" @@ -1155,7 +1165,7 @@ bool {0}::setHeaderData(int section, Qt::Orientation orientation, const QVariant write!(w, "role == Qt::{} || ", role_name(role))?; } writeln!(w, "role == Qt::UserRole + {}) {{", i)?; - let ii = if o.object_type == ObjectType::List { + let ii = if o.object_type.is_list() { ".row()" } else { "" @@ -1207,7 +1217,7 @@ fn constructor_args_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<( write!(w, ", void (*)({}*)", o.name)?; } } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { write!( w, ", @@ -1226,7 +1236,7 @@ fn constructor_args_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<( o.name )?; } - if o.object_type == ObjectType::Tree { + if o.object_type.is_tree() { write!( w, ", @@ -1262,7 +1272,7 @@ fn constructor_args(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) -> write!(w, ",\n {}", changed_f(o, name))?; } } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!( w, ", @@ -1308,7 +1318,7 @@ fn constructor_args(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) -> o.column_count() - 1 )?; } - if o.object_type == ObjectType::Tree { + if o.object_type.is_tree() { writeln!( w, ", @@ -1408,6 +1418,7 @@ pub fn write_header(conf: &Config) -> Result<()> { } writeln!(h, " #include +#include #include ")?; for name in conf.objects.keys() { @@ -1506,7 +1517,7 @@ namespace {{", writeln!(w, "}}")?; for o in conf.objects.values() { - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { write_cpp_model(&mut w, o)?; } writeln!(w, "extern \"C\" {{")?; diff --git a/src/rust.rs b/src/rust.rs index e752540..170aead 100644 --- a/src/rust.rs +++ b/src/rust.rs @@ -83,14 +83,14 @@ fn r_constructor_args_decl(r: &mut Vec, name: &str, o: &Object, conf: &Confi )?; } } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { write!( r, ",\n {}_new_data_ready: fn(*mut {}QObject)", snake_case(name), o.name )?; - } else if o.object_type == ObjectType::Tree { + } else if o.object_type.is_tree() { write!( r, ",\n {}_new_data_ready: fn(*mut {}QObject, index: COption)", @@ -98,13 +98,13 @@ fn r_constructor_args_decl(r: &mut Vec, name: &str, o: &Object, conf: &Confi o.name )?; } - if o.object_type != ObjectType::Object { - let index_decl = if o.object_type == ObjectType::Tree { + if o.object_type.is_model() { + let index_decl = if o.object_type.is_tree() { " index: COption," } else { "" }; - let dest_decl = if o.object_type == ObjectType::Tree { + let dest_decl = if o.object_type.is_tree() { " index: COption," } else { "" @@ -156,7 +156,7 @@ fn r_constructor_args(r: &mut Vec, name: &str, o: &Object, conf: &Config) -> snake_case(name) )?; } - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!( r, " new_data_ready: {}_new_data_ready,", @@ -164,8 +164,8 @@ fn r_constructor_args(r: &mut Vec, name: &str, o: &Object, conf: &Config) -> )?; } let mut model = String::new(); - if o.object_type != ObjectType::Object { - let type_ = if o.object_type == ObjectType::List { + if o.object_type.is_model() { + let type_ = if o.object_type.is_list() { "List" } else { "Tree" @@ -311,9 +311,9 @@ pub struct {0}Emitter {{ o.name )?; } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!(r, " new_data_ready: fn(*mut {}QObject),", o.name)?; - } else if o.object_type == ObjectType::Tree { + } else if o.object_type.is_tree() { writeln!( r, " new_data_ready: fn(*mut {}QObject, index: COption),", @@ -348,7 +348,7 @@ impl {0}Emitter {{ snake_case(name), )?; } - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!(r, " new_data_ready: self.new_data_ready,")?; } writeln!( @@ -378,7 +378,7 @@ impl {0}Emitter {{ )?; } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!( r, " pub fn new_data_ready(&mut self) {{ @@ -388,7 +388,7 @@ impl {0}Emitter {{ }} }}" )?; - } else if o.object_type == ObjectType::Tree { + } else if o.object_type.is_tree() { writeln!( r, " pub fn new_data_ready(&mut self, item: Option) {{ @@ -401,8 +401,8 @@ impl {0}Emitter {{ } let mut model_struct = String::new(); - if o.object_type != ObjectType::Object { - let type_ = if o.object_type == ObjectType::List { + if o.object_type.is_model() { + let type_ = if o.object_type.is_list() { "List" } else { "Tree" @@ -414,7 +414,7 @@ impl {0}Emitter {{ let mut dest = ""; let mut dest_decl = ""; let mut dest_c_decl = ""; - if o.object_type == ObjectType::Tree { + if o.object_type.is_tree() { index_decl = " index: Option,"; index_c_decl = " index: COption,"; index = " index.into(),"; @@ -550,7 +550,7 @@ pub trait {}Trait {{ f.return_type.rust_type() )?; } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!( r, " fn row_count(&self) -> usize; @@ -562,7 +562,7 @@ pub trait {}Trait {{ fn fetch_more(&mut self) {{}} fn sort(&mut self, _: u8, _: SortOrder) {{}}" )?; - } else if o.object_type == ObjectType::Tree { + } else if o.object_type.is_tree() { writeln!( r, " fn row_count(&self, _: Option) -> usize; @@ -577,7 +577,7 @@ pub trait {}Trait {{ fn row(&self, index: usize) -> usize;" )?; } - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { for (name, ip) in &o.item_properties { let name = snake_case(name); writeln!( @@ -851,7 +851,7 @@ pub unsafe extern \"C\" fn {}_set_none(ptr: *mut {}) {{ for f in &o.functions { write_function(r, f, &lcname, o)?; } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!( r, " @@ -885,7 +885,7 @@ pub unsafe extern \"C\" fn {1}_sort( }}", o.name, lcname )?; - } else if o.object_type == ObjectType::Tree { + } else if o.object_type.is_tree() { writeln!( r, " @@ -952,8 +952,8 @@ pub unsafe extern \"C\" fn {1}_row(ptr: *const {0}, index: usize) -> c_int {{ o.name, lcname )?; } - if o.object_type != ObjectType::Object { - let (index_decl, index) = if o.object_type == ObjectType::Tree { + if o.object_type.is_model() { + let (index_decl, index) = if o.object_type.is_tree() { (", index: usize", "index") } else { (", row: c_int", "to_usize(row)") @@ -1114,7 +1114,7 @@ fn write_rust_types(conf: &Config, r: &mut Vec) -> Result<()> { let mut has_list_or_tree = false; for o in conf.objects.values() { - has_list_or_tree |= o.object_type != ObjectType::Object; + has_list_or_tree |= o.object_type.is_model(); for p in o.properties.values() { has_option |= p.optional; has_string |= p.property_type == Type::Simple(SimpleType::QString); @@ -1288,7 +1288,7 @@ use {}{}::*;", } fn write_rust_implementation_object(r: &mut Vec, o: &Object) -> Result<()> { - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!(r, "#[derive(Default, Clone)]")?; writeln!(r, "struct {}Item {{", o.name)?; for (name, ip) in &o.item_properties { @@ -1308,10 +1308,10 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) -> Result<()> { } let mut model_struct = String::new(); writeln!(r, "pub struct {} {{\n emit: {0}Emitter,", o.name)?; - if o.object_type == ObjectType::List { + if o.object_type.is_list() { model_struct = format!(", model: {}List", o.name); writeln!(r, " model: {}List,", o.name)?; - } else if o.object_type == ObjectType::Tree { + } else if o.object_type.is_tree() { model_struct = format!(", model: {}Tree", o.name); writeln!(r, " model: {}Tree,", o.name)?; } @@ -1319,7 +1319,7 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) -> Result<()> { let lc = snake_case(name); writeln!(r, " {}: {},", lc, rust_type(p))?; } - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!(r, " list: Vec<{}Item>,", o.name)?; } writeln!(r, "}}\n")?; @@ -1336,7 +1336,7 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) -> Result<()> { emit,", o.name, model_struct )?; - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { writeln!(r, " model,")?; writeln!(r, " list: Vec::new(),")?; } @@ -1415,12 +1415,12 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) -> Result<()> { )?; } } - if o.object_type == ObjectType::List { + if o.object_type.is_list() { writeln!( r, " fn row_count(&self) -> usize {{\n self.list.len()\n }}" )?; - } else if o.object_type == ObjectType::Tree { + } else if o.object_type.is_tree() { writeln!( r, " fn row_count(&self, item: Option) -> usize {{ @@ -1444,7 +1444,7 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) -> Result<()> { }}" )?; } - if o.object_type != ObjectType::Object { + if o.object_type.is_model() { for (name, ip) in &o.item_properties { let lc = snake_case(name); writeln!(