Warning, /sdk/rust-qt-binding-generator/src/configuration.rs is written in an unsupported language. File is not indexed.

0001 use configuration_private::*;
0002 use serde_json;
0003 use std::collections::{BTreeMap, BTreeSet};
0004 use std::error::Error;
0005 use std::fs;
0006 use std::path::{Path, PathBuf};
0007 use std::rc::Rc;
0008 use toml;
0009 
0010 mod json {
0011     use super::Rust;
0012     use std::collections::BTreeMap;
0013     use std::path::PathBuf;
0014 
0015     pub fn false_bool() -> bool {
0016         false
0017     }
0018 
0019     fn object() -> super::ObjectType {
0020         super::ObjectType::Object
0021     }
0022 
0023     #[derive(Deserialize)]
0024     #[serde(deny_unknown_fields)]
0025     pub struct Config {
0026         #[serde(rename = "cppFile")]
0027         pub cpp_file: PathBuf,
0028         pub objects: BTreeMap<String, Object>,
0029         pub rust: Rust,
0030         #[serde(default = "false_bool")]
0031         pub overwrite_implementation: bool,
0032     }
0033 
0034     #[derive(Deserialize)]
0035     #[serde(deny_unknown_fields)]
0036     pub struct Object {
0037         #[serde(default)]
0038         pub functions: BTreeMap<String, super::Function>,
0039         #[serde(rename = "itemProperties", default)]
0040         pub item_properties: BTreeMap<String, super::ItemProperty>,
0041         #[serde(rename = "type", default = "object")]
0042         pub object_type: super::ObjectType,
0043         #[serde(default)]
0044         pub properties: BTreeMap<String, Property>,
0045     }
0046 
0047     #[derive(Deserialize)]
0048     #[serde(deny_unknown_fields)]
0049     pub struct Property {
0050         #[serde(default = "false_bool")]
0051         pub optional: bool,
0052         #[serde(rename = "type")]
0053         pub property_type: String,
0054         #[serde(rename = "rustByFunction", default = "false_bool")]
0055         pub rust_by_function: bool,
0056         #[serde(default = "false_bool")]
0057         pub write: bool,
0058     }
0059 }
0060 
0061 pub enum RustEdition {
0062     Rust2015,
0063     Rust2018,
0064     Rust2021,
0065     Unknown,
0066 }
0067 
0068 impl<'a> ::std::convert::From<Option<&'a str>> for RustEdition {
0069     fn from(str: Option<&'a str>) -> RustEdition {
0070         match str {
0071             None | Some("2015") => RustEdition::Rust2015,
0072             Some("2018") => RustEdition::Rust2018,
0073             Some("2021") => RustEdition::Rust2021,
0074             _ => RustEdition::Unknown,
0075         }
0076     }
0077 }
0078 
0079 pub struct Config {
0080     pub config_file: PathBuf,
0081     pub cpp_file: PathBuf,
0082     pub objects: BTreeMap<String, Rc<Object>>,
0083     pub rust: Rust,
0084     pub rust_edition: RustEdition,
0085     pub overwrite_implementation: bool,
0086 }
0087 
0088 impl ConfigPrivate for Config {
0089     fn types(&self) -> BTreeSet<String> {
0090         let mut ops = BTreeSet::new();
0091         for o in self.objects.values() {
0092             for p in o.properties.values() {
0093                 ops.insert(p.type_name().into());
0094             }
0095             for p in o.item_properties.values() {
0096                 ops.insert(p.type_name().into());
0097             }
0098             for f in o.functions.values() {
0099                 ops.insert(f.return_type.name().into());
0100                 for a in &f.arguments {
0101                     ops.insert(a.type_name().into());
0102                 }
0103             }
0104         }
0105         ops
0106     }
0107     fn optional_types(&self) -> BTreeSet<String> {
0108         let mut ops = BTreeSet::new();
0109         for o in self.objects.values() {
0110             for p in o.properties.values() {
0111                 if p.optional {
0112                     ops.insert(p.type_name().into());
0113                 }
0114             }
0115             for p in o.item_properties.values() {
0116                 if p.optional {
0117                     ops.insert(p.type_name().into());
0118                 }
0119             }
0120             if o.object_type != ObjectType::Object {
0121                 ops.insert("quintptr".into());
0122             }
0123         }
0124         ops
0125     }
0126     fn has_list_or_tree(&self) -> bool {
0127         self.objects
0128             .values()
0129             .any(|o| o.object_type == ObjectType::List || o.object_type == ObjectType::Tree)
0130     }
0131 }
0132 
0133 #[derive(PartialEq)]
0134 pub struct Object {
0135     pub name: String,
0136     pub functions: BTreeMap<String, Function>,
0137     pub item_properties: BTreeMap<String, ItemProperty>,
0138     pub object_type: ObjectType,
0139     pub properties: BTreeMap<String, Property>,
0140 }
0141 
0142 impl ObjectPrivate for Object {
0143     fn contains_object(&self) -> bool {
0144         self.properties.values().any(|p| p.is_object())
0145     }
0146     fn column_count(&self) -> usize {
0147         let mut column_count = 1;
0148         for ip in self.item_properties.values() {
0149             column_count = column_count.max(ip.roles.len());
0150         }
0151         column_count
0152     }
0153 }
0154 
0155 #[derive(PartialEq)]
0156 pub struct Property {
0157     pub optional: bool,
0158     pub property_type: Type,
0159     pub rust_by_function: bool,
0160     pub write: bool,
0161 }
0162 
0163 impl PropertyPrivate for Property {
0164     fn is_object(&self) -> bool {
0165         self.property_type.is_object()
0166     }
0167     fn is_complex(&self) -> bool {
0168         self.property_type.is_complex()
0169     }
0170     fn c_get_type(&self) -> String {
0171         let name = self.property_type.name();
0172         name.to_string() + "*, " + &name.to_lowercase() + "_set"
0173     }
0174 }
0175 
0176 impl TypeName for Property {
0177     fn type_name(&self) -> &str {
0178         self.property_type.name()
0179     }
0180 }
0181 
0182 #[derive(Deserialize)]
0183 #[serde(deny_unknown_fields)]
0184 pub struct Rust {
0185     pub dir: PathBuf,
0186     #[serde(rename = "implementationModule")]
0187     pub implementation_module: String,
0188     #[serde(rename = "interfaceModule")]
0189     pub interface_module: String,
0190 }
0191 
0192 #[derive(Deserialize, Clone, Copy, PartialEq, Eq)]
0193 pub enum ObjectType {
0194     Object,
0195     List,
0196     Tree,
0197 }
0198 
0199 #[derive(Deserialize, Clone, Copy, PartialEq, Eq)]
0200 pub enum SimpleType {
0201     QString,
0202     QByteArray,
0203     #[serde(rename = "bool")]
0204     Bool,
0205     #[serde(rename = "float")]
0206     Float,
0207     #[serde(rename = "double")]
0208     Double,
0209     #[serde(rename = "void")]
0210     Void,
0211     #[serde(rename = "qint8")]
0212     Qint8,
0213     #[serde(rename = "qint16")]
0214     Qint16,
0215     #[serde(rename = "qint32")]
0216     Qint32,
0217     #[serde(rename = "qint64")]
0218     Qint64,
0219     #[serde(rename = "quint8")]
0220     QUint8,
0221     #[serde(rename = "quint16")]
0222     QUint16,
0223     #[serde(rename = "quint32")]
0224     QUint32,
0225     #[serde(rename = "quint64")]
0226     QUint64,
0227 }
0228 
0229 impl SimpleTypePrivate for SimpleType {
0230     fn name(&self) -> &str {
0231         match self {
0232             SimpleType::QString => "QString",
0233             SimpleType::QByteArray => "QByteArray",
0234             SimpleType::Bool => "bool",
0235             SimpleType::Float => "float",
0236             SimpleType::Double => "double",
0237             SimpleType::Void => "void",
0238             SimpleType::Qint8 => "qint8",
0239             SimpleType::Qint16 => "qint16",
0240             SimpleType::Qint32 => "qint32",
0241             SimpleType::Qint64 => "qint64",
0242             SimpleType::QUint8 => "quint8",
0243             SimpleType::QUint16 => "quint16",
0244             SimpleType::QUint32 => "quint32",
0245             SimpleType::QUint64 => "quint64",
0246         }
0247     }
0248     fn cpp_set_type(&self) -> &str {
0249         match self {
0250             SimpleType::QString => "const QString&",
0251             SimpleType::QByteArray => "const QByteArray&",
0252             _ => self.name(),
0253         }
0254     }
0255     fn c_set_type(&self) -> &str {
0256         match self {
0257             SimpleType::QString => "qstring_t",
0258             SimpleType::QByteArray => "qbytearray_t",
0259             _ => self.name(),
0260         }
0261     }
0262     fn rust_type(&self) -> &str {
0263         match self {
0264             SimpleType::QString => "String",
0265             SimpleType::QByteArray => "Vec<u8>",
0266             SimpleType::Bool => "bool",
0267             SimpleType::Float => "f32",
0268             SimpleType::Double => "f64",
0269             SimpleType::Void => "()",
0270             SimpleType::Qint8 => "i8",
0271             SimpleType::Qint16 => "i16",
0272             SimpleType::Qint32 => "i32",
0273             SimpleType::Qint64 => "i64",
0274             SimpleType::QUint8 => "u8",
0275             SimpleType::QUint16 => "u16",
0276             SimpleType::QUint32 => "u32",
0277             SimpleType::QUint64 => "u64",
0278         }
0279     }
0280     fn rust_type_init(&self) -> &str {
0281         match self {
0282             SimpleType::QString => "String::new()",
0283             SimpleType::QByteArray => "Vec::new()",
0284             SimpleType::Bool => "false",
0285             SimpleType::Float | SimpleType::Double => "0.0",
0286             SimpleType::Void => "()",
0287             _ => "0",
0288         }
0289     }
0290     fn is_complex(&self) -> bool {
0291         self == &SimpleType::QString || self == &SimpleType::QByteArray
0292     }
0293 }
0294 
0295 #[derive(PartialEq)]
0296 pub enum Type {
0297     Simple(SimpleType),
0298     Object(Rc<Object>),
0299 }
0300 
0301 impl TypePrivate for Type {
0302     fn is_object(&self) -> bool {
0303         matches!(self, Type::Object(_))
0304     }
0305     fn is_complex(&self) -> bool {
0306         match self {
0307             Type::Simple(simple) => simple.is_complex(),
0308             _ => false,
0309         }
0310     }
0311     fn name(&self) -> &str {
0312         match self {
0313             Type::Simple(s) => s.name(),
0314             Type::Object(o) => &o.name,
0315         }
0316     }
0317     fn cpp_set_type(&self) -> &str {
0318         match self {
0319             Type::Simple(s) => s.cpp_set_type(),
0320             Type::Object(o) => &o.name,
0321         }
0322     }
0323     fn c_set_type(&self) -> &str {
0324         match self {
0325             Type::Simple(s) => s.c_set_type(),
0326             Type::Object(o) => &o.name,
0327         }
0328     }
0329     fn rust_type(&self) -> &str {
0330         match self {
0331             Type::Simple(s) => s.rust_type(),
0332             Type::Object(o) => &o.name,
0333         }
0334     }
0335     fn rust_type_init(&self) -> &str {
0336         match self {
0337             Type::Simple(s) => s.rust_type_init(),
0338             Type::Object(_) => unimplemented!(),
0339         }
0340     }
0341 }
0342 
0343 #[derive(Deserialize, Clone, PartialEq, Eq)]
0344 #[serde(deny_unknown_fields)]
0345 pub struct ItemProperty {
0346     #[serde(rename = "type")]
0347     pub item_property_type: SimpleType,
0348     #[serde(default = "json::false_bool")]
0349     pub optional: bool,
0350     #[serde(default)]
0351     pub roles: Vec<Vec<String>>,
0352     #[serde(rename = "rustByValue", default = "json::false_bool")]
0353     pub rust_by_value: bool,
0354     #[serde(default = "json::false_bool")]
0355     pub write: bool,
0356 }
0357 
0358 impl TypeName for ItemProperty {
0359     fn type_name(&self) -> &str {
0360         self.item_property_type.name()
0361     }
0362 }
0363 
0364 impl ItemPropertyPrivate for ItemProperty {
0365     fn is_complex(&self) -> bool {
0366         self.item_property_type.is_complex()
0367     }
0368     fn cpp_set_type(&self) -> String {
0369         let t = self.item_property_type.cpp_set_type().to_string();
0370         if self.optional {
0371             return "option_".to_string() + &t;
0372         }
0373         t
0374     }
0375     fn c_get_type(&self) -> String {
0376         let name = self.item_property_type.name();
0377         name.to_string() + "*, " + &name.to_lowercase() + "_set"
0378     }
0379     fn c_set_type(&self) -> &str {
0380         self.item_property_type.c_set_type()
0381     }
0382 }
0383 
0384 #[derive(Deserialize, Clone, PartialEq, Eq)]
0385 #[serde(deny_unknown_fields)]
0386 pub struct Function {
0387     #[serde(rename = "return")]
0388     pub return_type: SimpleType,
0389     #[serde(rename = "mut", default = "json::false_bool")]
0390     pub mutable: bool,
0391     #[serde(default)]
0392     pub arguments: Vec<Argument>,
0393 }
0394 
0395 impl TypeName for Function {
0396     fn type_name(&self) -> &str {
0397         self.return_type.name()
0398     }
0399 }
0400 
0401 #[derive(Deserialize, Clone, PartialEq, Eq)]
0402 #[serde(deny_unknown_fields)]
0403 pub struct Argument {
0404     pub name: String,
0405     #[serde(rename = "type")]
0406     pub argument_type: SimpleType,
0407 }
0408 
0409 impl TypeName for Argument {
0410     fn type_name(&self) -> &str {
0411         self.argument_type.name()
0412     }
0413 }
0414 
0415 fn post_process_property(
0416     a: (&String, &json::Property),
0417     b: &mut BTreeMap<String, Rc<Object>>,
0418     c: &BTreeMap<String, json::Object>,
0419 ) -> Result<Property, Box<dyn Error>> {
0420     let name = &a.1.property_type;
0421     let t = match serde_json::from_str::<SimpleType>(&format!("\"{}\"", name)) {
0422         Err(_) => {
0423             if b.get(name).is_none() {
0424                 if let Some(object) = c.get(name) {
0425                     post_process_object((name, object), b, c)?;
0426                 } else {
0427                     return Err(format!("Type {} cannot be found.", name).into());
0428                 }
0429             }
0430             Type::Object(Rc::clone(b.get(name).unwrap()))
0431         }
0432         Ok(simple) => Type::Simple(simple),
0433     };
0434     Ok(Property {
0435         property_type: t,
0436         optional: a.1.optional,
0437         rust_by_function: a.1.rust_by_function,
0438         write: a.1.write,
0439     })
0440 }
0441 
0442 fn post_process_object(
0443     a: (&String, &json::Object),
0444     b: &mut BTreeMap<String, Rc<Object>>,
0445     c: &BTreeMap<String, json::Object>,
0446 ) -> Result<(), Box<dyn Error>> {
0447     let mut properties = BTreeMap::default();
0448     for p in &a.1.properties {
0449         properties.insert(p.0.clone(), post_process_property(p, b, c)?);
0450     }
0451     let object = Rc::new(Object {
0452         name: a.0.clone(),
0453         object_type: a.1.object_type,
0454         functions: a.1.functions.clone(),
0455         item_properties: a.1.item_properties.clone(),
0456         properties,
0457     });
0458     b.insert(a.0.clone(), object);
0459     Ok(())
0460 }
0461 
0462 fn post_process(config_file: &Path, json: json::Config) -> Result<Config, Box<dyn Error>> {
0463     let mut objects = BTreeMap::default();
0464     for object in &json.objects {
0465         post_process_object(object, &mut objects, &json.objects)?;
0466     }
0467 
0468     let rust_edition: RustEdition = {
0469         let mut buf = config_file.to_path_buf();
0470         buf.pop();
0471         buf.push(&json.rust.dir);
0472         buf.push("Cargo.toml");
0473         if !buf.exists() {
0474             return Err(format!("{} does not exist.", buf.display()).into());
0475         }
0476         let manifest: toml::Value = fs::read_to_string(&buf)?.parse()?;
0477         manifest["package"]
0478             .get("edition")
0479             .and_then(|val| val.as_str())
0480             .into()
0481     };
0482 
0483     Ok(Config {
0484         config_file: config_file.into(),
0485         cpp_file: json.cpp_file,
0486         objects,
0487         rust: json.rust,
0488         rust_edition,
0489         overwrite_implementation: json.overwrite_implementation,
0490     })
0491 }
0492 
0493 pub fn parse<P: AsRef<Path>>(config_file: P) -> Result<Config, Box<dyn Error>> {
0494     let contents = fs::read_to_string(config_file.as_ref())?;
0495     let config: json::Config = serde_json::from_str(&contents)?;
0496     post_process(config_file.as_ref(), config)
0497 }