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 }