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 }