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