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 }