From b3e43ae1d265627d6e507d64791a8ab80ea8cdee Mon Sep 17 00:00:00 2001 From: Jos van den Oever Date: Fri, 28 Sep 2018 18:05:10 +0200 Subject: [PATCH] Handle result of write! and writeln! This is probably the patch with the largest amount of question marks added to code ever. --- src/configuration.rs | 16 +- src/cpp.rs | 400 +++++++++++++++++++++---------------------- src/lib.rs | 2 +- src/rust.rs | 324 +++++++++++++++++------------------ src/util.rs | 6 +- 5 files changed, 368 insertions(+), 380 deletions(-) diff --git a/src/configuration.rs b/src/configuration.rs index 3a31744..d2d7001 100644 --- a/src/configuration.rs +++ b/src/configuration.rs @@ -1,14 +1,14 @@ -use std::collections::{BTreeMap, BTreeSet}; -use std::path::{Path, PathBuf}; -use std::error::Error; use serde_json; +use std::collections::{BTreeMap, BTreeSet}; +use std::error::Error; use std::fs; +use std::path::{Path, PathBuf}; use std::rc::Rc; mod json { - use std::path::PathBuf; - use std::collections::BTreeMap; use super::Rust; + use std::collections::BTreeMap; + use std::path::PathBuf; pub fn false_bool() -> bool { false @@ -103,9 +103,9 @@ impl Config { ops } pub fn has_list_or_tree(&self) -> bool { - self.objects.values().any(|o| { - o.object_type == ObjectType::List || o.object_type == ObjectType::Tree - }) + self.objects + .values() + .any(|o| o.object_type == ObjectType::List || o.object_type == ObjectType::Tree) } } diff --git a/src/cpp.rs b/src/cpp.rs index 8f82f09..68d4e41 100644 --- a/src/cpp.rs +++ b/src/cpp.rs @@ -1,5 +1,5 @@ +use configuration::{Config, Function, ItemProperty, Object, ObjectType, Type}; use std::io::{Result, Write}; -use configuration::{Config, Function, Object, ObjectType, ItemProperty, Type}; use util::{snake_case, write_if_different}; fn property_type(p: &ItemProperty) -> String { @@ -57,12 +57,12 @@ fn write_header_item_model(h: &mut Vec, o: &Object) -> Result<()> { bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override; Q_INVOKABLE bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; Q_INVOKABLE bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;" - ); + )?; if model_is_writable(o) { writeln!( h, " bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;" - ); + )?; } for (name, ip) in &o.item_properties { let r = property_type(ip); @@ -72,29 +72,28 @@ fn write_header_item_model(h: &mut Vec, o: &Object) -> Result<()> { r.clone() }; if o.object_type == ObjectType::List { - writeln!(h, " Q_INVOKABLE {} {}(int row) const;", r, name); + writeln!(h, " Q_INVOKABLE {} {}(int row) const;", r, name)?; if ip.write { writeln!( h, " Q_INVOKABLE bool set{}(int row, {} value);", upper_initial(name), rw - ); + )?; } } else { writeln!( h, " Q_INVOKABLE {} {}(const QModelIndex& index) const;", - r, - name - ); + r, name + )?; if ip.write { writeln!( h, " Q_INVOKABLE bool set{}(const QModelIndex& index, {} value);", upper_initial(name), rw - ); + )?; } } } @@ -108,7 +107,7 @@ private: QHash, QVariant> m_headerData; void initHeaderData(); void updatePersistentIndexes();" - ); + )?; Ok(()) } @@ -121,10 +120,10 @@ class {} : public {} Q_OBJECT", o.name, base_type(o) - ); + )?; for object in conf.objects.values() { if object.contains_object() && o.name != object.name { - writeln!(h, " friend class {};", object.name); + writeln!(h, " friend class {};", object.name)?; } } writeln!( @@ -132,17 +131,17 @@ class {} : public {} "public: class Private; private:" - ); + )?; for (name, p) in &o.properties { if p.is_object() { - writeln!(h, " {}* const m_{};", p.type_name(), name); + writeln!(h, " {}* const m_{};", p.type_name(), name)?; } } writeln!( h, " Private * m_d; bool m_ownsPrivate;" - ); + )?; for (name, p) in &o.properties { let mut t = if p.optional && !p.is_complex() { "QVariant" @@ -162,7 +161,7 @@ private:" } else { String::new() } - ); + )?; } writeln!( h, @@ -171,41 +170,41 @@ public: explicit {0}(QObject *parent = nullptr); ~{0}();", o.name - ); + )?; for (name, p) in &o.properties { if p.is_object() { - writeln!(h, " const {}* {}() const;", p.type_name(), name); - writeln!(h, " {}* {}();", p.type_name(), name); + writeln!(h, " const {}* {}() const;", p.type_name(), name)?; + writeln!(h, " {}* {}();", p.type_name(), name)?; } else { let (t, t2) = if p.optional && !p.is_complex() { ("QVariant", "const QVariant&") } else { (p.type_name(), p.property_type.cpp_set_type()) }; - writeln!(h, " {} {}() const;", t, name); + writeln!(h, " {} {}() const;", t, name)?; if p.write { - writeln!(h, " void set{}({} v);", upper_initial(name), t2); + writeln!(h, " void set{}({} v);", upper_initial(name), t2)?; } } } for (name, f) in &o.functions { - write!(h, " Q_INVOKABLE {} {}(", f.return_type.name(), name); + write!(h, " Q_INVOKABLE {} {}(", f.return_type.name(), name)?; for (i, a) in f.arguments.iter().enumerate() { if i != 0 { - write!(h, ", "); + write!(h, ", ")?; } - write!(h, "{} {}", a.argument_type.cpp_set_type(), a.name); + write!(h, "{} {}", a.argument_type.cpp_set_type(), a.name)?; } - writeln!(h, "){};", if f.mutable { "" } else { " const" }); + writeln!(h, "){};", if f.mutable { "" } else { " const" })?; } if base_type(o) == "QAbstractItemModel" { write_header_item_model(h, o)?; } - writeln!(h, "Q_SIGNALS:"); + writeln!(h, "Q_SIGNALS:")?; for name in o.properties.keys() { - writeln!(h, " void {}Changed();", name); + writeln!(h, " void {}Changed();", name)?; } - writeln!(h, "}};"); + writeln!(h, "}};")?; Ok(()) } @@ -225,11 +224,11 @@ fn write_function_c_decl( o: &Object, ) -> Result<()> { let lc = snake_case(name); - write!(w, " "); + write!(w, " ")?; if f.return_type.is_complex() { - write!(w, "void"); + write!(w, "void")?; } else { - write!(w, "{}", f.type_name()); + write!(w, "{}", f.type_name())?; } let name = format!("{}_{}", lcname, lc); write!( @@ -238,37 +237,37 @@ fn write_function_c_decl( name, if f.mutable { "" } else { "const " }, o.name - ); + )?; // write all the input arguments, for QString and QByteArray, write // pointers to their content and the length for a in &f.arguments { if a.type_name() == "QString" { - write!(w, ", const ushort*, int"); + write!(w, ", const ushort*, int")?; } else if a.type_name() == "QByteArray" { - write!(w, ", const char*, int"); + write!(w, ", const char*, int")?; } else { - write!(w, ", {}", a.type_name()); + write!(w, ", {}", a.type_name())?; } } // If the return type is QString or QByteArray, append a pointer to the // variable that will be set to the argument list. Also add a setter // function. if f.return_type.name() == "QString" { - write!(w, ", QString*, qstring_set"); + write!(w, ", QString*, qstring_set")?; } else if f.return_type.name() == "QByteArray" { - write!(w, ", QByteArray*, qbytearray_set"); + write!(w, ", QByteArray*, qbytearray_set")?; } - writeln!(w, ");"); + writeln!(w, ");")?; Ok(()) } fn write_object_c_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { let lcname = snake_case(&o.name); - write!(w, " {}::Private* {}_new(", o.name, lcname); + write!(w, " {}::Private* {}_new(", o.name, lcname)?; constructor_args_decl(w, o, conf)?; - writeln!(w, ");"); - writeln!(w, " void {}_free({}::Private*);", lcname, o.name); + writeln!(w, ");")?; + writeln!(w, " void {}_free({}::Private*);", lcname, o.name)?; for (name, p) in &o.properties { let base = format!("{}_{}", lcname, snake_case(name)); if p.is_object() { @@ -278,7 +277,7 @@ fn write_object_c_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> p.type_name(), base, o.name - ); + )?; } else if p.is_complex() { writeln!( w, @@ -286,7 +285,7 @@ fn write_object_c_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> base, o.name, p.c_get_type() - ); + )?; } else if p.optional { writeln!( w, @@ -294,7 +293,7 @@ fn write_object_c_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> p.type_name(), base, o.name - ); + )?; } else { writeln!( w, @@ -302,7 +301,7 @@ fn write_object_c_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> p.type_name(), base, o.name - ); + )?; } if p.write { let mut t = p.property_type.c_set_type(); @@ -311,9 +310,9 @@ fn write_object_c_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> } else if t == "qbytearray_t" { t = "const char* bytes, int len"; } - writeln!(w, " void {}_set({}::Private*, {});", base, o.name, t); + writeln!(w, " void {}_set({}::Private*, {});", base, o.name, t)?; if p.optional { - writeln!(w, " void {}_set_none({}::Private*);", base, o.name); + writeln!(w, " void {}_set_none({}::Private*);", base, o.name)?; } } } @@ -323,15 +322,16 @@ fn write_object_c_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> Ok(()) } -fn initialize_members_zero(w: &mut Vec, o: &Object) { +fn initialize_members_zero(w: &mut Vec, o: &Object) -> Result<()> { for (name, p) in &o.properties { if p.is_object() { - writeln!(w, " m_{}(new {}(false, this)),", name, p.type_name()); + writeln!(w, " m_{}(new {}(false, this)),", name, p.type_name())?; } } + Ok(()) } -fn initialize_members(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) { +fn initialize_members(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) -> Result<()> { for (name, p) in &o.properties { if let Type::Object(object) = &p.property_type { writeln!( @@ -341,16 +341,17 @@ fn initialize_members(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) name, snake_case(&o.name), snake_case(name) - ); - initialize_members(w, &format!("m_{}->", name), object, conf); + )?; + initialize_members(w, &format!("m_{}->", name), object, conf)?; } } + Ok(()) } -fn connect(w: &mut Vec, d: &str, o: &Object, conf: &Config) { +fn connect(w: &mut Vec, d: &str, o: &Object, conf: &Config) -> Result<()> { for (name, p) in &o.properties { if let Type::Object(object) = &p.property_type { - connect(w, &format!("{}->m_{}", d, name), object, conf); + connect(w, &format!("{}->m_{}", d, name), object, conf)?; } } if o.object_type != ObjectType::Object { @@ -359,10 +360,10 @@ fn connect(w: &mut Vec, d: &str, o: &Object, conf: &Config) { " connect({}, &{1}::newDataReady, {0}, [this](const QModelIndex& i) {{ {0}->fetchMore(i); }}, Qt::QueuedConnection);", - d, - o.name - ); + d, o.name + )?; } + Ok(()) } fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { @@ -373,16 +374,16 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { {}(parent),", o.name, base_type(o) - ); - initialize_members_zero(w, o); + )?; + initialize_members_zero(w, o)?; writeln!( w, " m_d(nullptr), m_ownsPrivate(false) {{" - ); + )?; if o.object_type != ObjectType::Object { - writeln!(w, " initHeaderData();"); + writeln!(w, " initHeaderData();")?; } writeln!( w, @@ -392,20 +393,20 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { {}(parent),", o.name, base_type(o) - ); - initialize_members_zero(w, o); - write!(w, " m_d({}_new(this", lcname); - constructor_args(w, "", o, conf); + )?; + initialize_members_zero(w, o)?; + write!(w, " m_d({}_new(this", lcname)?; + constructor_args(w, "", o, conf)?; writeln!( w, ")), m_ownsPrivate(true) {{" - ); - initialize_members(w, "", o, conf); - connect(w, "this", o, conf); + )?; + initialize_members(w, "", o, conf)?; + connect(w, "this", o, conf)?; if o.object_type != ObjectType::Object { - writeln!(w, " initHeaderData();"); + writeln!(w, " initHeaderData();")?; } writeln!( w, @@ -416,11 +417,10 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { {1}_free(m_d); }} }}", - o.name, - lcname - ); + o.name, lcname + )?; if o.object_type != ObjectType::Object { - writeln!(w, "void {}::initHeaderData() {{", o.name); + writeln!(w, "void {}::initHeaderData() {{", o.name)?; for col in 0..o.column_count { for (name, ip) in &o.item_properties { let empty = Vec::new(); @@ -431,11 +431,11 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { " m_headerData.insert(qMakePair({}, Qt::DisplayRole), QVariant(\"{}\"));", col, name - ); + )?; } } } - writeln!(w, "}}"); + writeln!(w, "}}")?; } for (name, p) in &o.properties { @@ -454,7 +454,7 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { p.type_name(), o.name, name - ); + )?; } else if p.is_complex() { writeln!( w, @@ -469,7 +469,7 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { name, base, p.type_name().to_lowercase() - ); + )?; } else if p.optional { writeln!( w, @@ -482,10 +482,8 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { }} return r; }}", - o.name, - name, - base - ); + o.name, name, base + )?; } else { writeln!( w, @@ -497,7 +495,7 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { o.name, name, base - ); + )?; } if p.write { let t = if p.optional && !p.is_complex() { @@ -505,56 +503,56 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { } else { p.property_type.cpp_set_type() }; - writeln!(w, "void {}::set{}({} v) {{", o.name, upper_initial(name), t); + writeln!(w, "void {}::set{}({} v) {{", o.name, upper_initial(name), t)?; if p.optional { if p.is_complex() { - writeln!(w, " if (v.isNull()) {{"); + writeln!(w, " if (v.isNull()) {{")?; } else { writeln!( w, " if (v.isNull() || !v.canConvert<{}>()) {{", p.type_name() - ); + )?; } - writeln!(w, " {}_set_none(m_d);", base); - writeln!(w, " }} else {{"); + writeln!(w, " {}_set_none(m_d);", base)?; + writeln!(w, " }} else {{")?; if p.type_name() == "QString" { writeln!( w, " {}_set(m_d, reinterpret_cast(v.data()), v.size());", base - ); + )?; } else if p.type_name() == "QByteArray" { - writeln!(w, " {}_set(m_d, v.data(), v.size());", base); + writeln!(w, " {}_set(m_d, v.data(), v.size());", base)?; } else if p.optional { writeln!( w, " {}_set(m_d, v.value<{}>());", base, p.type_name() - ); + )?; } else { - writeln!(w, " {}_set(m_d, v);", base); + writeln!(w, " {}_set(m_d, v);", base)?; } - writeln!(w, " }}"); + writeln!(w, " }}")?; } else if p.type_name() == "QString" { writeln!( w, " {}_set(m_d, reinterpret_cast(v.data()), v.size());", base - ); + )?; } else if p.type_name() == "QByteArray" { - writeln!(w, " {}_set(m_d, v.data(), v.size());", base); + writeln!(w, " {}_set(m_d, v.data(), v.size());", base)?; } else { - writeln!(w, " {}_set(m_d, v);", base); + writeln!(w, " {}_set(m_d, v);", base)?; } - writeln!(w, "}}"); + writeln!(w, "}}")?; } } for (name, f) in &o.functions { let base = format!("{}_{}", lcname, snake_case(name)); - write!(w, "{} {}::{}(", f.type_name(), o.name, name); + write!(w, "{} {}::{}(", f.type_name(), o.name, name)?; for (i, a) in f.arguments.iter().enumerate() { write!( w, @@ -562,9 +560,9 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { a.argument_type.cpp_set_type(), a.name, if i + 1 < f.arguments.len() { ", " } else { "" } - ); + )?; } - writeln!(w, "){}\n{{", if f.mutable { "" } else { " const" }); + writeln!(w, "){}\n{{", if f.mutable { "" } else { " const" })?; let mut arg_list = String::new(); for a in &f.arguments { if a.type_name() == "QString" { @@ -584,7 +582,7 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { f.type_name(), base, arg_list - ); + )?; } else if f.return_type.name() == "QByteArray" { writeln!( w, @@ -594,11 +592,11 @@ fn write_cpp_object(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { f.type_name(), base, arg_list - ); + )?; } else { - writeln!(w, " return {}(m_d{});", base, arg_list); + writeln!(w, " return {}(m_d{});", base, arg_list)?; } - writeln!(w, "}}"); + writeln!(w, "}}")?; } Ok(()) } @@ -629,18 +627,16 @@ fn write_model_getter_setter( let mut r = property_type(ip); if o.object_type == ObjectType::List { idx = ", row"; - writeln!(w, "{} {}::{}(int row) const\n{{", r, o.name, name); + writeln!(w, "{} {}::{}(int row) const\n{{", r, o.name, name)?; } else { writeln!( w, "{} {}::{}(const QModelIndex& index) const\n{{", - r, - o.name, - name - ); + r, o.name, name + )?; } if ip.type_name() == "QString" { - writeln!(w, " QString s;"); + writeln!(w, " QString s;")?; writeln!( w, " {}_data_{}(m_d{}, &s, set_{});", @@ -648,10 +644,10 @@ fn write_model_getter_setter( snake_case(name), idx, ip.type_name().to_lowercase() - ); - writeln!(w, " return s;"); + )?; + writeln!(w, " return s;")?; } else if ip.type_name() == "QByteArray" { - writeln!(w, " QByteArray b;"); + writeln!(w, " QByteArray b;")?; writeln!( w, " {}_data_{}(m_d{}, &b, set_{});", @@ -659,18 +655,18 @@ fn write_model_getter_setter( snake_case(name), idx, ip.type_name().to_lowercase() - ); - writeln!(w, " return b;"); + )?; + writeln!(w, " return b;")?; } else if ip.optional { - writeln!(w, " QVariant v;"); + writeln!(w, " QVariant v;")?; writeln!( w, " v = {}_data_{}(m_d{});", lcname, snake_case(name), idx - ); - writeln!(w, " return v;"); + )?; + writeln!(w, " return v;")?; } else { writeln!( w, @@ -678,9 +674,9 @@ fn write_model_getter_setter( lcname, snake_case(name), idx - ); + )?; } - writeln!(w, "}}\n"); + writeln!(w, "}}\n")?; if !ip.write { return Ok(()); } @@ -697,7 +693,7 @@ fn write_model_getter_setter( o.name, upper_initial(name), r - ); + )?; } else { writeln!( w, @@ -705,23 +701,23 @@ fn write_model_getter_setter( o.name, upper_initial(name), r - ); + )?; } - writeln!(w, " bool set = false;"); + writeln!(w, " bool set = false;")?; if ip.optional { let mut test = "value.isNull()".to_string(); if !ip.is_complex() { test += " || !value.isValid()"; } - writeln!(w, " if ({}) {{", test); + writeln!(w, " if ({}) {{", test)?; writeln!( w, " set = {}_set_data_{}_none(m_d{});", lcname, snake_case(name), idx - ); - writeln!(w, " }} else {{"); + )?; + writeln!(w, " }} else {{")?; } if ip.optional && !ip.is_complex() { writeln!( @@ -730,7 +726,7 @@ fn write_model_getter_setter( return false; }}", ip.type_name() - ); + )?; writeln!( w, " set = {}_set_data_{}(m_d{}, value.value<{}>());", @@ -738,7 +734,7 @@ fn write_model_getter_setter( snake_case(name), idx, ip.type_name() - ); + )?; } else { let mut val = "value"; if ip.is_complex() { @@ -755,10 +751,10 @@ fn write_model_getter_setter( snake_case(name), idx, val - ); + )?; } if ip.optional { - writeln!(w, " }}"); + writeln!(w, " }}")?; } if o.object_type == ObjectType::List { writeln!( @@ -770,7 +766,7 @@ fn write_model_getter_setter( return set; }} " - ); + )?; } else { writeln!( w, @@ -780,7 +776,7 @@ fn write_model_getter_setter( return set; }} " - ); + )?; } Ok(()) } @@ -792,7 +788,7 @@ fn write_cpp_model(w: &mut Vec, o: &Object) -> Result<()> { } else { (", int", ", index.row()") }; - writeln!(w, "extern \"C\" {{"); + writeln!(w, "extern \"C\" {{")?; for (name, ip) in &o.item_properties { if ip.is_complex() { @@ -804,7 +800,7 @@ fn write_cpp_model(w: &mut Vec, o: &Object) -> Result<()> { o.name, index_decl, ip.c_get_type() - ); + )?; } else { writeln!( w, @@ -814,20 +810,20 @@ fn write_cpp_model(w: &mut Vec, o: &Object) -> Result<()> { snake_case(name), o.name, index_decl - ); + )?; } if ip.write { let a = format!(" bool {}_set_data_{}", lcname, snake_case(name)); let b = format!("({}::Private*{}", o.name, index_decl); if ip.type_name() == "QString" { - writeln!(w, "{}{}, const ushort* s, int len);", a, b); + writeln!(w, "{}{}, const ushort* s, int len);", a, b)?; } else if ip.type_name() == "QByteArray" { - writeln!(w, "{}{}, const char* s, int len);", a, b); + writeln!(w, "{}{}, const char* s, int len);", a, b)?; } else { - writeln!(w, "{}{}, {});", a, b, ip.c_set_type()); + writeln!(w, "{}{}, {});", a, b, ip.c_set_type())?; } if ip.optional { - writeln!(w, "{}_none{});", a, b); + writeln!(w, "{}_none{});", a, b)?; } } } @@ -836,7 +832,7 @@ fn write_cpp_model(w: &mut Vec, o: &Object) -> Result<()> { " void {}_sort({}::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder);", lcname, o.name - ); + )?; if o.object_type == ObjectType::List { writeln!( w, @@ -897,10 +893,8 @@ void {0}::fetchMore(const QModelIndex &parent) }} }} void {0}::updatePersistentIndexes() {{}}", - o.name, - lcname, - o.column_count - ); + o.name, lcname, o.column_count + )?; } else { writeln!( w, @@ -1008,10 +1002,8 @@ void {0}::updatePersistentIndexes() {{ }} changePersistentIndexList(from, to); }}", - o.name, - lcname, - o.column_count - ); + o.name, lcname, o.column_count + )?; } writeln!( w, @@ -1023,16 +1015,15 @@ void {0}::sort(int column, Qt::SortOrder order) Qt::ItemFlags {0}::flags(const QModelIndex &i) const {{ auto flags = QAbstractItemModel::flags(i);", - o.name, - lcname - ); + o.name, lcname + )?; for col in 0..o.column_count { if is_column_write(o, col) { - writeln!(w, " if (i.column() == {}) {{", col); - writeln!(w, " flags |= Qt::ItemIsEditable;\n }}"); + writeln!(w, " if (i.column() == {}) {{", col)?; + writeln!(w, " flags |= Qt::ItemIsEditable;\n }}")?; } } - writeln!(w, " return flags;\n}}\n"); + writeln!(w, " return flags;\n}}\n")?; for ip in &o.item_properties { write_model_getter_setter(w, index, ip.0, ip.1, o)?; } @@ -1043,11 +1034,11 @@ Qt::ItemFlags {0}::flags(const QModelIndex &i) const Q_ASSERT(rowCount(index.parent()) > index.row()); switch (index.column()) {{", o.name - ); + )?; for col in 0..o.column_count { - writeln!(w, " case {}:", col); - writeln!(w, " switch (role) {{"); + writeln!(w, " case {}:", col)?; + writeln!(w, " switch (role) {{")?; for (i, (name, ip)) in o.item_properties.iter().enumerate() { let empty = Vec::new(); let roles = ip.roles.get(col).unwrap_or(&empty); @@ -1055,33 +1046,31 @@ Qt::ItemFlags {0}::flags(const QModelIndex &i) const continue; } for role in roles { - writeln!(w, " case Qt::{}:", role_name(role)); + writeln!(w, " case Qt::{}:", role_name(role))?; } - writeln!(w, " case Qt::UserRole + {}:", i); + writeln!(w, " case Qt::UserRole + {}:", i)?; let ii = if o.object_type == ObjectType::List { ".row()" } else { "" }; if ip.optional && !ip.is_complex() { - writeln!(w, " return {}(index{});", name, ii); + writeln!(w, " return {}(index{});", name, ii)?; } else if ip.optional { writeln!( w, " return cleanNullQVariant(QVariant::fromValue({}(index{})));", - name, - ii - ); + name, ii + )?; } else { writeln!( w, " return QVariant::fromValue({}(index{}));", - name, - ii - ); + name, ii + )?; } } - writeln!(w, " }}\n break;"); + writeln!(w, " }}\n break;")?; } writeln!( w, @@ -1103,9 +1092,9 @@ int {}::role(const char* name) const {{ QHash {0}::roleNames() const {{ QHash names = QAbstractItemModel::roleNames();", o.name - ); + )?; for (i, (name, _)) in o.item_properties.iter().enumerate() { - writeln!(w, " names.insert(Qt::UserRole + {}, \"{}\");", i, name); + writeln!(w, " names.insert(Qt::UserRole + {}, \"{}\");", i, name)?; } writeln!( w, @@ -1129,18 +1118,18 @@ bool {0}::setHeaderData(int section, Qt::Orientation orientation, const QVariant }} ", o.name - ); + )?; if model_is_writable(o) { writeln!( w, "bool {}::setData(const QModelIndex &index, const QVariant &value, int role)\n{{", o.name - ); + )?; for col in 0..o.column_count { if !is_column_write(o, col) { continue; } - writeln!(w, " if (index.column() == {}) {{", col); + writeln!(w, " if (index.column() == {}) {{", col)?; for (i, (name, ip)) in o.item_properties.iter().enumerate() { if !ip.write { continue; @@ -1150,11 +1139,11 @@ bool {0}::setHeaderData(int section, Qt::Orientation orientation, const QVariant if col > 0 && roles.is_empty() { continue; } - write!(w, " if ("); + write!(w, " if (")?; for role in roles { - write!(w, "role == Qt::{} || ", role_name(role)); + write!(w, "role == Qt::{} || ", role_name(role))?; } - writeln!(w, "role == Qt::UserRole + {}) {{", i); + writeln!(w, "role == Qt::UserRole + {}) {{", i)?; let ii = if o.object_type == ObjectType::List { ".row()" } else { @@ -1166,7 +1155,7 @@ bool {0}::setHeaderData(int section, Qt::Orientation orientation, const QVariant " return set{}(index{}, value);", upper_initial(name), ii - ); + )?; } else { let pre = if ip.optional { "!value.isValid() || value.isNull() ||" @@ -1178,33 +1167,33 @@ bool {0}::setHeaderData(int section, Qt::Orientation orientation, const QVariant " if ({}value.canConvert(qMetaTypeId<{}>())) {{", pre, ip.type_name() - ); + )?; writeln!( w, " return set{}(index{}, value.value<{}>());", upper_initial(name), ii, ip.type_name() - ); - writeln!(w, " }}"); + )?; + writeln!(w, " }}")?; } - writeln!(w, " }}"); + writeln!(w, " }}")?; } - writeln!(w, " }}"); + writeln!(w, " }}")?; } - writeln!(w, " return false;\n}}\n"); + writeln!(w, " return false;\n}}\n")?; } Ok(()) } fn constructor_args_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<()> { - write!(w, "{}*", o.name); + write!(w, "{}*", o.name)?; for p in o.properties.values() { if let Type::Object(object) = &p.property_type { - write!(w, ", "); + write!(w, ", ")?; constructor_args_decl(w, object, conf)?; } else { - write!(w, ", void (*)({}*)", o.name); + write!(w, ", void (*)({}*)", o.name)?; } } if o.object_type == ObjectType::List { @@ -1224,7 +1213,7 @@ fn constructor_args_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<( void (*)({0}*, int, int), void (*)({0}*)", o.name - ); + )?; } if o.object_type == ObjectType::Tree { write!( @@ -1243,7 +1232,7 @@ fn constructor_args_decl(w: &mut Vec, o: &Object, conf: &Config) -> Result<( void (*)({0}*, option_quintptr, int, int), void (*)({0}*)", o.name - ); + )?; } Ok(()) } @@ -1252,14 +1241,14 @@ fn changed_f(o: &Object, p_name: &str) -> String { lower_initial(&o.name) + &upper_initial(p_name) + "Changed" } -fn constructor_args(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) { +fn constructor_args(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) -> Result<()> { let lcname = snake_case(&o.name); for (name, p) in &o.properties { if let Type::Object(object) = &p.property_type { - write!(w, ", {}m_{}", prefix, name); - constructor_args(w, &format!("m_{}->", name), object, conf); + write!(w, ", {}m_{}", prefix, name)?; + constructor_args(w, &format!("m_{}->", name), object, conf)?; } else { - write!(w, ",\n {}", changed_f(o, name)); + write!(w, ",\n {}", changed_f(o, name))?; } } if o.object_type == ObjectType::List { @@ -1306,7 +1295,7 @@ fn constructor_args(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) { }}", o.name, o.column_count - 1 - ); + )?; } if o.object_type == ObjectType::Tree { writeln!( @@ -1380,8 +1369,9 @@ fn constructor_args(w: &mut Vec, prefix: &str, o: &Object, conf: &Config) { o.name, lcname, o.column_count - 1 - ); + )?; } + Ok(()) } pub fn write_header(conf: &Config) -> Result<()> { @@ -1404,15 +1394,15 @@ pub fn write_header(conf: &Config) -> Result<()> { #include ", guard - ); + )?; for name in conf.objects.keys() { - writeln!(h, "class {};", name); + writeln!(h, "class {};", name)?; } for object in conf.objects.values() { write_header_object(&mut h, object, conf)?; } - writeln!(h, "#endif // {}", guard); + writeln!(h, "#endif // {}", guard)?; write_if_different(h_file, &h)?; Ok(()) @@ -1430,7 +1420,7 @@ pub fn write_cpp(conf: &Config) -> Result<()> { namespace {{", file_name - ); + )?; for option in conf.optional_types() { if option != "QString" && option != "QByteArray" { writeln!( @@ -1449,7 +1439,7 @@ namespace {{", }}; static_assert(std::is_pod::value, \"option_{0} must be a POD type.\");", option - ); + )?; } } if conf.types().contains("QString") { @@ -1460,7 +1450,7 @@ namespace {{", void set_qstring(QString* val, const char* utf8, int nbytes) {{ *val = QString::fromUtf8(utf8, nbytes); }}" - ); + )?; } if conf.types().contains("QByteArray") { writeln!( @@ -1475,7 +1465,7 @@ namespace {{", v->append(bytes, nbytes); }} }}" - ); + )?; } if conf.has_list_or_tree() { writeln!( @@ -1488,26 +1478,26 @@ namespace {{", inline QVariant cleanNullQVariant(const QVariant& v) {{ return (v.isNull()) ?QVariant() :v; }}" - ); + )?; } for (name, o) in &conf.objects { for (p_name, p) in &o.properties { if p.is_object() { continue; } - writeln!(w, " inline void {}({}* o)", changed_f(o, p_name), name); - writeln!(w, " {{\n Q_EMIT o->{}Changed();\n }}", p_name); + writeln!(w, " inline void {}({}* o)", changed_f(o, p_name), name)?; + writeln!(w, " {{\n Q_EMIT o->{}Changed();\n }}", p_name)?; } } - writeln!(w, "}}"); + writeln!(w, "}}")?; for o in conf.objects.values() { if o.object_type != ObjectType::Object { write_cpp_model(&mut w, o)?; } - writeln!(w, "extern \"C\" {{"); + writeln!(w, "extern \"C\" {{")?; write_object_c_decl(&mut w, o, conf)?; - writeln!(w, "}};\n"); + writeln!(w, "}};\n")?; } for o in conf.objects.values() { diff --git a/src/lib.rs b/src/lib.rs index fc0e27d..2677df8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,9 +8,9 @@ mod cpp; mod rust; mod util; +use std::error::Error; use std::fmt::Display; use std::path::Path; -use std::error::Error; pub fn generate_rust_qt_bindings + Display>( config_file: P, diff --git a/src/rust.rs b/src/rust.rs index fa7a2ac..8c6b968 100644 --- a/src/rust.rs +++ b/src/rust.rs @@ -1,4 +1,6 @@ -use configuration::{Config, Function, ItemProperty, Object, ObjectType, Property, SimpleType, Type}; +use configuration::{ + Config, Function, ItemProperty, Object, ObjectType, Property, SimpleType, Type, +}; use std::io::{Result, Write}; use util::{snake_case, write_if_different}; @@ -64,12 +66,12 @@ fn rust_type_init(p: &Property) -> &str { p.property_type.rust_type_init() } -fn r_constructor_args_decl(r: &mut Vec, name: &str, o: &Object, conf: &Config) { - write!(r, " {}: *mut {}QObject", snake_case(name), o.name); +fn r_constructor_args_decl(r: &mut Vec, name: &str, o: &Object, conf: &Config) -> Result<()> { + write!(r, " {}: *mut {}QObject", snake_case(name), o.name)?; for (p_name, p) in &o.properties { if let Type::Object(object) = &p.property_type { - writeln!(r, ","); - r_constructor_args_decl(r, p_name, object, conf); + writeln!(r, ",")?; + r_constructor_args_decl(r, p_name, object, conf)?; } else { write!( r, @@ -77,7 +79,7 @@ fn r_constructor_args_decl(r: &mut Vec, name: &str, o: &Object, conf: &Confi snake_case(name), snake_case(p_name), o.name - ); + )?; } } if o.object_type == ObjectType::List { @@ -86,14 +88,14 @@ fn r_constructor_args_decl(r: &mut Vec, name: &str, o: &Object, conf: &Confi ",\n {}_new_data_ready: fn(*const {}QObject)", snake_case(name), o.name - ); + )?; } else if o.object_type == ObjectType::Tree { write!( r, ",\n {}_new_data_ready: fn(*const {}QObject, index: COption)", snake_case(name), o.name - ); + )?; } if o.object_type != ObjectType::Object { let index_decl = if o.object_type == ObjectType::Tree { @@ -124,14 +126,15 @@ fn r_constructor_args_decl(r: &mut Vec, name: &str, o: &Object, conf: &Confi index_decl, snake_case(name), dest_decl - ); + )?; } + Ok(()) } -fn r_constructor_args(r: &mut Vec, name: &str, o: &Object, conf: &Config) { +fn r_constructor_args(r: &mut Vec, name: &str, o: &Object, conf: &Config) -> Result<()> { for (name, p) in &o.properties { if let Type::Object(object) = &p.property_type { - r_constructor_args(r, name, object, conf); + r_constructor_args(r, name, object, conf)?; } } writeln!( @@ -140,7 +143,7 @@ fn r_constructor_args(r: &mut Vec, name: &str, o: &Object, conf: &Config) { qobject: Arc::new(Mutex::new({0})),", snake_case(name), o.name - ); + )?; for (p_name, p) in &o.properties { if p.is_object() { continue; @@ -150,14 +153,14 @@ fn r_constructor_args(r: &mut Vec, name: &str, o: &Object, conf: &Config) { " {}_changed: {}_{0}_changed,", snake_case(p_name), snake_case(name) - ); + )?; } if o.object_type != ObjectType::Object { writeln!( r, " new_data_ready: {}_new_data_ready,", snake_case(name) - ); + )?; } let mut model = String::new(); if o.object_type != ObjectType::Object { @@ -186,7 +189,7 @@ fn r_constructor_args(r: &mut Vec, name: &str, o: &Object, conf: &Config) { o.name, type_, snake_case(name) - ); + )?; } write!( r, @@ -194,16 +197,21 @@ fn r_constructor_args(r: &mut Vec, name: &str, o: &Object, conf: &Config) { snake_case(name), o.name, model - ); + )?; for (name, p) in &o.properties { if p.is_object() { - write!(r, ",\n d_{}", snake_case(name)); + write!(r, ",\n d_{}", snake_case(name))?; } } - writeln!(r, ");"); + writeln!(r, ");") } -fn write_function(r: &mut Vec, (name, f): (&String, &Function), lcname: &str, o: &Object) { +fn write_function( + r: &mut Vec, + (name, f): (&String, &Function), + lcname: &str, + o: &Object, +) -> Result<()> { let lc = snake_case(name); write!( r, @@ -214,17 +222,17 @@ pub unsafe extern \"C\" fn {}_{}(ptr: *{} {}", lc, if f.mutable { "mut" } else { "const" }, o.name - ); + )?; // write all the input arguments, for QString and QByteArray, write // pointers to their content and the length which is int in Qt for a in &f.arguments { - write!(r, ", "); + write!(r, ", ")?; if a.argument_type.name() == "QString" { - write!(r, "{}_str: *const c_ushort, {0}_len: c_int", a.name); + write!(r, "{}_str: *const c_ushort, {0}_len: c_int", a.name)?; } else if a.argument_type.name() == "QByteArray" { - write!(r, "{}_str: *const c_char, {0}_len: c_int", a.name); + write!(r, "{}_str: *const c_char, {0}_len: c_int", a.name)?; } else { - write!(r, "{}: {}", a.name, a.argument_type.rust_type()); + write!(r, "{}: {}", a.name, a.argument_type.rust_type())?; } } // If the return type is QString or QByteArray, append a pointer to the @@ -235,9 +243,9 @@ pub unsafe extern \"C\" fn {}_{}(ptr: *{} {}", r, ", d: *mut {}, set: fn(*mut {0}, str: *const c_char, len: c_int)) {{", f.return_type.name() - ); + )?; } else { - writeln!(r, ") -> {} {{", f.return_type.rust_type()); + writeln!(r, ") -> {} {{", f.return_type.rust_type())?; } for a in &f.arguments { if a.argument_type.name() == "QString" { @@ -246,41 +254,41 @@ pub unsafe extern \"C\" fn {}_{}(ptr: *{} {}", " let mut {} = String::new(); set_string_from_utf16(&mut {0}, {0}_str, {0}_len);", a.name - ); + )?; } else if a.argument_type.name() == "QByteArray" { writeln!( r, " let {} = {{ slice::from_raw_parts({0}_str as *const u8, to_usize({0}_len)) }};", a.name - ); + )?; } } if f.mutable { - writeln!(r, " let o = &mut *ptr;"); + writeln!(r, " let o = &mut *ptr;")?; } else { - writeln!(r, " let o = &*ptr;"); + writeln!(r, " let o = &*ptr;")?; } - write!(r, " let r = o.{}(", lc); + write!(r, " let r = o.{}(", lc)?; for (i, a) in f.arguments.iter().enumerate() { if i > 0 { - write!(r, ", "); + write!(r, ", ")?; } - write!(r, "{}", a.name); + write!(r, "{}", a.name)?; } - writeln!(r, ");"); + writeln!(r, ");")?; if f.return_type.is_complex() { writeln!( r, " let s: *const c_char = r.as_ptr() as (*const c_char); set(d, s, r.len() as i32);" - ); + )?; } else { - writeln!(r, " r"); + writeln!(r, " r")?; } - writeln!(r, "}}"); + writeln!(r, "}}") } -fn write_rust_interface_object(r: &mut Vec, o: &Object, conf: &Config) { +fn write_rust_interface_object(r: &mut Vec, o: &Object, conf: &Config) -> Result<()> { let lcname = snake_case(&o.name); writeln!( r, @@ -291,7 +299,7 @@ pub struct {}QObject {{}} pub struct {0}Emitter {{ qobject: Arc>,", o.name - ); + )?; for (name, p) in &o.properties { if p.is_object() { continue; @@ -301,16 +309,16 @@ pub struct {0}Emitter {{ " {}_changed: fn(*const {}QObject),", snake_case(name), o.name - ); + )?; } if o.object_type == ObjectType::List { - writeln!(r, " new_data_ready: fn(*const {}QObject),", o.name); + writeln!(r, " new_data_ready: fn(*const {}QObject),", o.name)?; } else if o.object_type == ObjectType::Tree { writeln!( r, " new_data_ready: fn(*const {}QObject, index: COption),", o.name - ); + )?; } writeln!( r, @@ -323,7 +331,7 @@ impl {0}Emitter {{ *self.qobject.lock().unwrap() = null(); }}", o.name - ); + )?; for (name, p) in &o.properties { if p.is_object() { @@ -338,7 +346,7 @@ impl {0}Emitter {{ }} }}", snake_case(name) - ); + )?; } if o.object_type == ObjectType::List { @@ -350,7 +358,7 @@ impl {0}Emitter {{ (self.new_data_ready)(ptr); }} }}" - ); + )?; } else if o.object_type == ObjectType::Tree { writeln!( r, @@ -360,7 +368,7 @@ impl {0}Emitter {{ (self.new_data_ready)(ptr, item.into()); }} }}" - ); + )?; } let mut model_struct = String::new(); @@ -439,15 +447,8 @@ impl {0}{1} {{ pub fn end_remove_rows(&self) {{ (self.end_remove_rows)(self.qobject); }}", - o.name, - type_, - index_decl, - index, - index_c_decl, - dest_decl, - dest, - dest_c_decl - ); + o.name, type_, index_decl, index, index_c_decl, dest_decl, dest, dest_c_decl + )?; } write!( @@ -456,12 +457,11 @@ impl {0}{1} {{ pub trait {}Trait {{ fn new(emit: {0}Emitter{}", - o.name, - model_struct - ); + o.name, model_struct + )?; for (name, p) in &o.properties { if p.is_object() { - write!(r, ",\n {}: {}", snake_case(name), p.type_name()); + write!(r, ",\n {}: {}", snake_case(name), p.type_name())?; } } writeln!( @@ -469,12 +469,12 @@ pub trait {}Trait {{ ") -> Self; fn emit(&self) -> &{}Emitter;", o.name - ); + )?; for (name, p) in &o.properties { let lc = snake_case(name).to_lowercase(); if p.is_object() { - writeln!(r, " fn {}(&self) -> &{};", lc, rust_type(p)); - writeln!(r, " fn {}_mut(&mut self) -> &mut {};", lc, rust_type(p)); + writeln!(r, " fn {}(&self) -> &{};", lc, rust_type(p))?; + writeln!(r, " fn {}_mut(&mut self) -> &mut {};", lc, rust_type(p))?; } else { if p.rust_by_function { write!( @@ -482,19 +482,19 @@ pub trait {}Trait {{ " fn {}(&self, getter: F) where F: FnOnce({});", lc, rust_return_type(p) - ); + )?; } else { - writeln!(r, " fn {}(&self) -> {};", lc, rust_return_type(p)); + writeln!(r, " fn {}(&self) -> {};", lc, rust_return_type(p))?; } if p.write { if p.type_name() == "QByteArray" { if p.optional { - writeln!(r, " fn set_{}(&mut self, value: Option<&[u8]>);", lc); + writeln!(r, " fn set_{}(&mut self, value: Option<&[u8]>);", lc)?; } else { - writeln!(r, " fn set_{}(&mut self, value: &[u8]);", lc); + writeln!(r, " fn set_{}(&mut self, value: &[u8]);", lc)?; } } else { - writeln!(r, " fn set_{}(&mut self, value: {});", lc, rust_type(p)); + writeln!(r, " fn set_{}(&mut self, value: {});", lc, rust_type(p))?; } } } @@ -519,7 +519,7 @@ pub trait {}Trait {{ if f.mutable { "mut " } else { "" }, arg_list, f.return_type.rust_type() - ); + )?; } if o.object_type == ObjectType::List { writeln!( @@ -532,7 +532,7 @@ pub trait {}Trait {{ }} fn fetch_more(&mut self) {{}} fn sort(&mut self, u8, SortOrder) {{}}" - ); + )?; } else if o.object_type == ObjectType::Tree { writeln!( r, @@ -546,7 +546,7 @@ pub trait {}Trait {{ fn index(&self, item: Option, row: usize) -> usize; fn parent(&self, index: usize) -> Option; fn row(&self, index: usize) -> usize;" - ); + )?; } if o.object_type != ObjectType::Object { for (name, ip) in &o.item_properties { @@ -556,7 +556,7 @@ pub trait {}Trait {{ " fn {}(&self, index: usize) -> {};", name, rust_return_type_(ip) - ); + )?; if ip.write { if ip.item_property_type.name() == "QByteArray" { if ip.optional { @@ -564,13 +564,13 @@ pub trait {}Trait {{ r, " fn set_{}(&mut self, index: usize, Option<&[u8]>) -> bool;", name - ); + )?; } else { writeln!( r, " fn set_{}(&mut self, index: usize, &[u8]) -> bool;", name - ); + )?; } } else { writeln!( @@ -578,7 +578,7 @@ pub trait {}Trait {{ " fn set_{}(&mut self, index: usize, {}) -> bool;", name, rust_type_(ip) - ); + )?; } } } @@ -590,10 +590,10 @@ pub trait {}Trait {{ #[no_mangle] pub extern \"C\" fn {}_new(", lcname - ); - r_constructor_args_decl(r, &lcname, o, conf); - writeln!(r, ",\n) -> *mut {} {{", o.name); - r_constructor_args(r, &lcname, o, conf); + )?; + r_constructor_args_decl(r, &lcname, o, conf)?; + writeln!(r, ",\n) -> *mut {} {{", o.name)?; + r_constructor_args(r, &lcname, o, conf)?; writeln!( r, " Box::into_raw(Box::new(d_{})) @@ -603,9 +603,8 @@ pub extern \"C\" fn {}_new(", pub unsafe extern \"C\" fn {0}_free(ptr: *mut {}) {{ Box::from_raw(ptr).emit().clear(); }}", - lcname, - o.name - ); + lcname, o.name + )?; for (name, p) in &o.properties { let base = format!("{}_{}", lcname, snake_case(name)); @@ -621,7 +620,7 @@ pub unsafe extern \"C\" fn {}_get(ptr: *mut {}) -> *mut {} {{ o.name, rust_type(p), snake_case(name) - ); + )?; } else if p.is_complex() && !p.optional { if p.rust_by_function { writeln!( @@ -643,7 +642,7 @@ pub unsafe extern \"C\" fn {}_get( o.name, p.type_name(), snake_case(name) - ); + )?; } else { writeln!( r, @@ -663,7 +662,7 @@ pub unsafe extern \"C\" fn {}_get( o.name, p.type_name(), snake_case(name) - ); + )?; } if p.write && p.type_name() == "QString" { writeln!( @@ -679,7 +678,7 @@ pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: *const c_ushort, len: c_int) base, o.name, snake_case(name) - ); + )?; } else if p.write { writeln!( r, @@ -693,7 +692,7 @@ pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: *const c_char, len: c_int) {{ base, o.name, snake_case(name) - ); + )?; } } else if p.is_complex() { writeln!( @@ -716,7 +715,7 @@ pub unsafe extern \"C\" fn {}_get( o.name, p.type_name(), snake_case(name) - ); + )?; if p.write && p.type_name() == "QString" { writeln!( r, @@ -731,7 +730,7 @@ pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: *const c_ushort, len: c_int) base, o.name, snake_case(name) - ); + )?; } else if p.write { writeln!( r, @@ -745,7 +744,7 @@ pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: *const c_char, len: c_int) {{ base, o.name, snake_case(name) - ); + )?; } } else if p.optional { writeln!( @@ -762,7 +761,7 @@ pub unsafe extern \"C\" fn {}_get(ptr: *const {}) -> COption<{}> {{ o.name, p.property_type.rust_type(), snake_case(name) - ); + )?; if p.write { writeln!( r, @@ -775,7 +774,7 @@ pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: {}) {{ o.name, p.property_type.rust_type(), snake_case(name) - ); + )?; } } else { writeln!( @@ -789,7 +788,7 @@ pub unsafe extern \"C\" fn {}_get(ptr: *const {}) -> {} {{ o.name, rust_type(p), snake_case(name) - ); + )?; if p.write { writeln!( r, @@ -802,7 +801,7 @@ pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: {}) {{ o.name, rust_type(p), snake_case(name) - ); + )?; } } if p.write && p.optional { @@ -817,11 +816,11 @@ pub unsafe extern \"C\" fn {}_set_none(ptr: *mut {}) {{ base, o.name, snake_case(name) - ); + )?; } } for f in &o.functions { - write_function(r, f, &lcname, o); + write_function(r, f, &lcname, o)?; } if o.object_type == ObjectType::List { writeln!( @@ -855,9 +854,8 @@ pub unsafe extern \"C\" fn {1}_sort( ) {{ (&mut *ptr).sort(column, order) }}", - o.name, - lcname - ); + o.name, lcname + )?; } else if o.object_type == ObjectType::Tree { writeln!( r, @@ -922,9 +920,8 @@ pub unsafe extern \"C\" fn {1}_parent(ptr: *const {0}, index: usize) -> QModelIn pub unsafe extern \"C\" fn {1}_row(ptr: *const {0}, index: usize) -> c_int {{ to_c_int((&*ptr).row(index)) }}", - o.name, - lcname - ); + o.name, lcname + )?; } if o.object_type != ObjectType::Object { let (index_decl, index) = if o.object_type == ObjectType::Tree { @@ -954,7 +951,7 @@ pub unsafe extern \"C\" fn {}_data_{}( index_decl, ip.type_name(), index - ); + )?; } else if ip.is_complex() { writeln!( r, @@ -978,7 +975,7 @@ pub unsafe extern \"C\" fn {}_data_{}( index_decl, ip.type_name(), index - ); + )?; } else { writeln!( r, @@ -994,7 +991,7 @@ pub unsafe extern \"C\" fn {}_data_{}(ptr: *const {}{}) -> {} {{ index_decl, rust_c_type(ip), index - ); + )?; } if ip.write { let val = if ip.optional { "Some(v)" } else { "v" }; @@ -1018,7 +1015,7 @@ pub unsafe extern \"C\" fn {}_set_data_{}( index_decl, index, val - ); + )?; } else if ip.type_name() == "QByteArray" { writeln!( r, @@ -1038,7 +1035,7 @@ pub unsafe extern \"C\" fn {}_set_data_{}( index_decl, index, if ip.optional { "Some(slice)" } else { "slice" } - ); + )?; } else { let type_ = ip.item_property_type.rust_type(); writeln!( @@ -1058,7 +1055,7 @@ pub unsafe extern \"C\" fn {}_set_data_{}( type_, index, val - ); + )?; } } if ip.write && ip.optional { @@ -1074,13 +1071,14 @@ pub unsafe extern \"C\" fn {}_set_data_{}_none(ptr: *mut {}{}) -> bool {{ o.name, index_decl, index - ); + )?; } } } + Ok(()) } -fn write_rust_types(conf: &Config, r: &mut Vec) { +fn write_rust_types(conf: &Config, r: &mut Vec) -> Result<()> { let mut has_option = false; let mut has_string = false; let mut has_byte_array = false; @@ -1165,7 +1163,7 @@ fn set_string_from_utf16(s: &mut String, str: *const c_ushort, len: c_int) {{ s.extend(characters); }} " - ); + )?; } if has_byte_array { writeln!( @@ -1173,7 +1171,7 @@ fn set_string_from_utf16(s: &mut String, str: *const c_ushort, len: c_int) {{ " pub enum QByteArray {{}}" - ); + )?; } if has_list_or_tree { writeln!( @@ -1192,7 +1190,7 @@ pub struct QModelIndex {{ row: c_int, internal_id: usize, }}" - ); + )?; } if has_string || has_byte_array || has_list_or_tree { @@ -1207,7 +1205,7 @@ fn to_usize(n: c_int) -> usize {{ n as usize }} " - ); + )?; } if has_string || has_byte_array || has_list_or_tree { @@ -1221,8 +1219,9 @@ fn to_c_int(n: usize) -> c_int {{ n as c_int }} " - ); + )?; } + Ok(()) } pub fn write_interface(conf: &Config) -> Result<()> { @@ -1241,14 +1240,15 @@ use std::ptr::null; use {}::*;", conf.rust.implementation_module - ); + )?; - write_rust_types(conf, &mut r); + write_rust_types(conf, &mut r)?; for object in conf.objects.values() { - write_rust_interface_object(&mut r, object, conf); + write_rust_interface_object(&mut r, object, conf)?; } - let mut file = conf.config_file + let mut file = conf + .config_file .parent() .unwrap() .join(&conf.rust.dir) @@ -1258,10 +1258,10 @@ use {}::*;", write_if_different(file, &r) } -fn write_rust_implementation_object(r: &mut Vec, o: &Object) { +fn write_rust_implementation_object(r: &mut Vec, o: &Object) -> Result<()> { if o.object_type != ObjectType::Object { - writeln!(r, "#[derive(Default, Clone)]"); - writeln!(r, "struct {}Item {{", o.name); + writeln!(r, "#[derive(Default, Clone)]")?; + writeln!(r, "struct {}Item {{", o.name)?; for (name, ip) in &o.item_properties { let lc = snake_case(name); if ip.optional { @@ -1270,30 +1270,30 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { " {}: Option<{}>,", lc, ip.item_property_type.rust_type() - ); + )?; } else { - writeln!(r, " {}: {},", lc, ip.item_property_type.rust_type()); + writeln!(r, " {}: {},", lc, ip.item_property_type.rust_type())?; } } - writeln!(r, "}}\n"); + writeln!(r, "}}\n")?; } let mut model_struct = String::new(); - writeln!(r, "pub struct {} {{\n emit: {0}Emitter,", o.name); + writeln!(r, "pub struct {} {{\n emit: {0}Emitter,", o.name)?; if o.object_type == ObjectType::List { model_struct = format!(", model: {}List", o.name); - writeln!(r, " model: {}List,", o.name); + writeln!(r, " model: {}List,", o.name)?; } else if o.object_type == ObjectType::Tree { model_struct = format!(", model: {}Tree", o.name); - writeln!(r, " model: {}Tree,", o.name); + writeln!(r, " model: {}Tree,", o.name)?; } for (name, p) in &o.properties { let lc = snake_case(name); - writeln!(r, " {}: {},", lc, rust_type(p)); + writeln!(r, " {}: {},", lc, rust_type(p))?; } if o.object_type != ObjectType::Object { - writeln!(r, " list: Vec<{}Item>,", o.name); + writeln!(r, " list: Vec<{}Item>,", o.name)?; } - writeln!(r, "}}\n"); + writeln!(r, "}}\n")?; for (name, p) in &o.properties { if p.is_object() { model_struct += &format!(", {}: {}", name, p.type_name()); @@ -1305,19 +1305,18 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { fn new(emit: {0}Emitter{}) -> {0} {{ {0} {{ emit,", - o.name, - model_struct - ); + o.name, model_struct + )?; if o.object_type != ObjectType::Object { - writeln!(r, " model,"); - writeln!(r, " list: Vec::new(),"); + writeln!(r, " model,")?; + writeln!(r, " list: Vec::new(),")?; } for (name, p) in &o.properties { let lc = snake_case(name); if p.is_object() { - writeln!(r, " {},", lc); + writeln!(r, " {},", lc)?; } else { - writeln!(r, " {}: {},", lc, rust_type_init(p)); + writeln!(r, " {}: {},", lc, rust_type_init(p))?; } } writeln!( @@ -1328,7 +1327,7 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { &self.emit }}", o.name - ); + )?; for (name, p) in &o.properties { let lc = snake_case(name); if p.is_object() { @@ -1342,7 +1341,7 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { }}", lc, rust_return_type(p) - ); + )?; } else if p.rust_by_function { writeln!( r, @@ -1354,19 +1353,19 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { }}", lc, rust_return_type(p) - ); + )?; } else { - writeln!(r, " fn {}(&self) -> {} {{", lc, rust_return_type(p)); + writeln!(r, " fn {}(&self) -> {} {{", lc, rust_return_type(p))?; if p.is_complex() { if p.optional { - writeln!(r, " self.{}.as_ref().map(|p| &p[..])", lc); + writeln!(r, " self.{}.as_ref().map(|p| &p[..])", lc)?; } else { - writeln!(r, " &self.{}", lc); + writeln!(r, " &self.{}", lc)?; } } else { - writeln!(r, " self.{}", lc); + writeln!(r, " self.{}", lc)?; } - writeln!(r, " }}"); + writeln!(r, " }}")?; } if !p.is_object() && p.write { let bytearray = p.property_type == Type::Simple(SimpleType::QByteArray); @@ -1383,17 +1382,15 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { self.{0} = value{}; self.emit.{0}_changed(); }}", - lc, - t, - v - ); + lc, t, v + )?; } } if o.object_type == ObjectType::List { writeln!( r, " fn row_count(&self) -> usize {{\n self.list.len()\n }}" - ); + )?; } else if o.object_type == ObjectType::Tree { writeln!( r, @@ -1416,7 +1413,7 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { None }} }}" - ); + )?; } if o.object_type != ObjectType::Object { for (name, ip) in &o.item_properties { @@ -1426,19 +1423,19 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { " fn {}(&self, index: usize) -> {} {{", lc, rust_return_type_(ip) - ); + )?; if ip.is_complex() && ip.optional { writeln!( r, " self.list[index].{}.as_ref().map(|v| &v[..])", lc - ); + )?; } else if ip.is_complex() { - writeln!(r, " &self.list[index].{}", lc); + writeln!(r, " &self.list[index].{}", lc)?; } else { - writeln!(r, " self.list[index].{}", lc); + writeln!(r, " self.list[index].{}", lc)?; } - writeln!(r, " }}"); + writeln!(r, " }}")?; let bytearray = ip.item_property_type == SimpleType::QByteArray; if ip.write && bytearray && ip.optional { writeln!( @@ -1448,7 +1445,7 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { true }}", lc - ); + )?; } else if ip.write && bytearray { writeln!( r, @@ -1457,7 +1454,7 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { true }}", lc - ); + )?; } else if ip.write { writeln!( r, @@ -1467,15 +1464,16 @@ fn write_rust_implementation_object(r: &mut Vec, o: &Object) { }}", lc, rust_type_(ip) - ); + )?; } } } - writeln!(r, "}}"); + writeln!(r, "}}") } pub fn write_implementation(conf: &Config) -> Result<()> { - let mut file = conf.config_file + let mut file = conf + .config_file .parent() .unwrap() .join(&conf.rust.dir) @@ -1494,10 +1492,10 @@ pub fn write_implementation(conf: &Config) -> Result<()> { use {}::*; ", conf.rust.interface_module - ); + )?; for object in conf.objects.values() { - write_rust_implementation_object(&mut r, object); + write_rust_implementation_object(&mut r, object)?; } write_if_different(file, &r) } diff --git a/src/util.rs b/src/util.rs index c2a16a7..def551f 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,7 +1,7 @@ -use std::fs; -use std::path::Path; -use std::io::Result; use regex::Regex; +use std::fs; +use std::io::Result; +use std::path::Path; pub fn write_if_different>(path: P, contents: &[u8]) -> Result<()> { let old_contents = fs::read(&path).ok();