Warning, /sdk/rust-qt-binding-generator/src/rust.rs is written in an unsupported language. File is not indexed.
0001 //! `rust` is the module that generates the rust code for the binding 0002 0003 use configuration::*; 0004 use configuration_private::*; 0005 use std::io::{Result, Write}; 0006 use util::{snake_case, write_if_different}; 0007 0008 fn rust_type(p: &Property) -> String { 0009 if p.optional { 0010 return format!("Option<{}>", p.property_type.rust_type()); 0011 } 0012 p.property_type.rust_type().to_string() 0013 } 0014 0015 fn rust_type_(p: &ItemProperty) -> String { 0016 if p.optional { 0017 return format!("Option<{}>", p.item_property_type.rust_type()); 0018 } 0019 p.item_property_type.rust_type().to_string() 0020 } 0021 0022 fn rust_return_type(p: &Property) -> String { 0023 let mut type_: String = p.property_type.rust_type().to_string(); 0024 if type_ == "String" { 0025 type_ = "str".to_string(); 0026 } 0027 if type_ == "Vec<u8>" { 0028 type_ = "[u8]".to_string(); 0029 } 0030 if p.property_type.is_complex() { 0031 type_ = "&".to_string() + &type_; 0032 } 0033 if p.optional { 0034 return "Option<".to_string() + &type_ + ">"; 0035 } 0036 type_ 0037 } 0038 0039 fn rust_return_type_(p: &ItemProperty) -> String { 0040 let mut type_: String = p.item_property_type.rust_type().to_string(); 0041 if type_ == "String" && !p.rust_by_value { 0042 type_ = "str".to_string(); 0043 } 0044 if type_ == "Vec<u8>" && !p.rust_by_value { 0045 type_ = "[u8]".to_string(); 0046 } 0047 if p.item_property_type.is_complex() && !p.rust_by_value { 0048 type_ = "&".to_string() + &type_; 0049 } 0050 if p.optional { 0051 return "Option<".to_string() + &type_ + ">"; 0052 } 0053 type_ 0054 } 0055 0056 fn rust_c_type(p: &ItemProperty) -> String { 0057 if p.optional { 0058 return format!("COption<{}>", p.item_property_type.rust_type()); 0059 } 0060 p.item_property_type.rust_type().to_string() 0061 } 0062 0063 fn rust_type_init(p: &Property) -> &str { 0064 if p.optional { 0065 return "None"; 0066 } 0067 p.property_type.rust_type_init() 0068 } 0069 0070 fn r_constructor_args_decl(r: &mut Vec<u8>, name: &str, o: &Object, conf: &Config) -> Result<()> { 0071 write!(r, " {}: *mut {}QObject", snake_case(name), o.name)?; 0072 for (p_name, p) in &o.properties { 0073 if let Type::Object(object) = &p.property_type { 0074 writeln!(r, ",")?; 0075 r_constructor_args_decl(r, p_name, object, conf)?; 0076 } else { 0077 write!( 0078 r, 0079 ",\n {}_{}_changed: extern fn(*mut {}QObject)", 0080 snake_case(name), 0081 snake_case(p_name), 0082 o.name 0083 )?; 0084 } 0085 } 0086 if o.object_type == ObjectType::List { 0087 write!( 0088 r, 0089 ",\n {}_new_data_ready: extern fn(*mut {}QObject)", 0090 snake_case(name), 0091 o.name 0092 )?; 0093 } else if o.object_type == ObjectType::Tree { 0094 write!( 0095 r, 0096 ",\n {}_new_data_ready: extern fn(*mut {}QObject, index: COption<usize>)", 0097 snake_case(name), 0098 o.name 0099 )?; 0100 } 0101 if o.object_type != ObjectType::Object { 0102 let index_decl = if o.object_type == ObjectType::Tree { 0103 " index: COption<usize>," 0104 } else { 0105 "" 0106 }; 0107 let dest_decl = if o.object_type == ObjectType::Tree { 0108 " index: COption<usize>," 0109 } else { 0110 "" 0111 }; 0112 write!( 0113 r, 0114 ", 0115 {2}_layout_about_to_be_changed: extern fn(*mut {0}QObject), 0116 {2}_layout_changed: extern fn(*mut {0}QObject), 0117 {2}_data_changed: extern fn(*mut {0}QObject, usize, usize), 0118 {2}_begin_reset_model: extern fn(*mut {0}QObject), 0119 {2}_end_reset_model: extern fn(*mut {0}QObject), 0120 {2}_begin_insert_rows: extern fn(*mut {0}QObject,{1} usize, usize), 0121 {2}_end_insert_rows: extern fn(*mut {0}QObject), 0122 {2}_begin_move_rows: extern fn(*mut {0}QObject,{1} usize, usize,{3} usize), 0123 {2}_end_move_rows: extern fn(*mut {0}QObject), 0124 {2}_begin_remove_rows: extern fn(*mut {0}QObject,{1} usize, usize), 0125 {2}_end_remove_rows: extern fn(*mut {0}QObject)", 0126 o.name, 0127 index_decl, 0128 snake_case(name), 0129 dest_decl 0130 )?; 0131 } 0132 Ok(()) 0133 } 0134 0135 fn r_constructor_args(r: &mut Vec<u8>, name: &str, o: &Object, conf: &Config) -> Result<()> { 0136 for (name, p) in &o.properties { 0137 if let Type::Object(object) = &p.property_type { 0138 r_constructor_args(r, name, object, conf)?; 0139 } 0140 } 0141 writeln!( 0142 r, 0143 " let {}_emit = {}Emitter {{ 0144 qobject: Arc::new(AtomicPtr::new({0})),", 0145 snake_case(name), 0146 o.name 0147 )?; 0148 for (p_name, p) in &o.properties { 0149 if p.is_object() { 0150 continue; 0151 } 0152 writeln!( 0153 r, 0154 " {}_changed: {}_{0}_changed,", 0155 snake_case(p_name), 0156 snake_case(name) 0157 )?; 0158 } 0159 if o.object_type != ObjectType::Object { 0160 writeln!( 0161 r, 0162 " new_data_ready: {}_new_data_ready,", 0163 snake_case(name) 0164 )?; 0165 } 0166 let mut model = String::new(); 0167 if o.object_type != ObjectType::Object { 0168 let type_ = if o.object_type == ObjectType::List { 0169 "List" 0170 } else { 0171 "Tree" 0172 }; 0173 model.push_str(", model"); 0174 writeln!( 0175 r, 0176 " }}; 0177 let model = {}{} {{ 0178 qobject: {}, 0179 layout_about_to_be_changed: {2}_layout_about_to_be_changed, 0180 layout_changed: {2}_layout_changed, 0181 data_changed: {2}_data_changed, 0182 begin_reset_model: {2}_begin_reset_model, 0183 end_reset_model: {2}_end_reset_model, 0184 begin_insert_rows: {2}_begin_insert_rows, 0185 end_insert_rows: {2}_end_insert_rows, 0186 begin_move_rows: {2}_begin_move_rows, 0187 end_move_rows: {2}_end_move_rows, 0188 begin_remove_rows: {2}_begin_remove_rows, 0189 end_remove_rows: {2}_end_remove_rows,", 0190 o.name, 0191 type_, 0192 snake_case(name) 0193 )?; 0194 } 0195 write!( 0196 r, 0197 " }};\n let d_{} = {}::new({0}_emit{}", 0198 snake_case(name), 0199 o.name, 0200 model 0201 )?; 0202 for (name, p) in &o.properties { 0203 if p.is_object() { 0204 write!(r, ",\n d_{}", snake_case(name))?; 0205 } 0206 } 0207 writeln!(r, ");") 0208 } 0209 0210 fn write_function( 0211 r: &mut Vec<u8>, 0212 (name, f): (&String, &Function), 0213 lcname: &str, 0214 o: &Object, 0215 ) -> Result<()> { 0216 let lc = snake_case(name); 0217 write!( 0218 r, 0219 " 0220 #[no_mangle] 0221 pub unsafe extern \"C\" fn {}_{}(ptr: *{} {}", 0222 lcname, 0223 lc, 0224 if f.mutable { "mut" } else { "const" }, 0225 o.name 0226 )?; 0227 // write all the input arguments, for QString and QByteArray, write 0228 // pointers to their content and the length which is int in Qt 0229 for a in &f.arguments { 0230 write!(r, ", ")?; 0231 if a.argument_type.name() == "QString" { 0232 write!(r, "{}_str: *const c_ushort, {0}_len: c_int", a.name)?; 0233 } else if a.argument_type.name() == "QByteArray" { 0234 write!(r, "{}_str: *const c_char, {0}_len: c_int", a.name)?; 0235 } else { 0236 write!(r, "{}: {}", a.name, a.argument_type.rust_type())?; 0237 } 0238 } 0239 // If the return type is QString or QByteArray, append a pointer to the 0240 // variable that will be set to the argument list. Also add a setter 0241 // function. 0242 if f.return_type.is_complex() { 0243 writeln!( 0244 r, 0245 ", d: *mut {}, set: extern fn(*mut {0}, str: *const c_char, len: c_int)) {{", 0246 f.return_type.name() 0247 )?; 0248 } else if f.return_type == SimpleType::Void { 0249 writeln!(r, ") {{")?; 0250 } else { 0251 writeln!(r, ") -> {} {{", f.return_type.rust_type())?; 0252 } 0253 for a in &f.arguments { 0254 if a.argument_type.name() == "QString" { 0255 writeln!( 0256 r, 0257 " let mut {} = String::new(); 0258 set_string_from_utf16(&mut {0}, {0}_str, {0}_len);", 0259 a.name 0260 )?; 0261 } else if a.argument_type.name() == "QByteArray" { 0262 writeln!( 0263 r, 0264 " let {} = {{ slice::from_raw_parts({0}_str as *const u8, to_usize({0}_len)) }};", 0265 a.name 0266 )?; 0267 } 0268 } 0269 if f.mutable { 0270 writeln!(r, " let o = &mut *ptr;")?; 0271 } else { 0272 writeln!(r, " let o = &*ptr;")?; 0273 } 0274 if f.return_type.is_complex() { 0275 write!(r, " let r = o.{}(", lc)?; 0276 } else { 0277 write!(r, " o.{}(", lc)?; 0278 } 0279 for (i, a) in f.arguments.iter().enumerate() { 0280 if i > 0 { 0281 write!(r, ", ")?; 0282 } 0283 write!(r, "{}", a.name)?; 0284 } 0285 write!(r, ")")?; 0286 if f.return_type.is_complex() { 0287 writeln!(r, ";")?; 0288 writeln!( 0289 r, 0290 " let s: *const c_char = r.as_ptr() as *const c_char; 0291 set(d, s, r.len() as i32);" 0292 )?; 0293 } else { 0294 writeln!(r)?; 0295 } 0296 writeln!(r, "}}") 0297 } 0298 0299 fn write_rust_interface_object(r: &mut Vec<u8>, o: &Object, conf: &Config) -> Result<()> { 0300 let lcname = snake_case(&o.name); 0301 writeln!( 0302 r, 0303 " 0304 pub struct {}QObject {{}} 0305 0306 pub struct {0}Emitter {{ 0307 qobject: Arc<AtomicPtr<{0}QObject>>,", 0308 o.name 0309 )?; 0310 for (name, p) in &o.properties { 0311 if p.is_object() { 0312 continue; 0313 } 0314 writeln!( 0315 r, 0316 " {}_changed: extern fn(*mut {}QObject),", 0317 snake_case(name), 0318 o.name 0319 )?; 0320 } 0321 0322 if o.object_type == ObjectType::List { 0323 writeln!(r, " new_data_ready: extern fn(*mut {}QObject),", o.name)?; 0324 } else if o.object_type == ObjectType::Tree { 0325 writeln!( 0326 r, 0327 " new_data_ready: extern fn(*mut {}QObject, index: COption<usize>),", 0328 o.name 0329 )?; 0330 } 0331 writeln!( 0332 r, 0333 "}} 0334 0335 unsafe impl Send for {}Emitter {{}} 0336 0337 impl {0}Emitter {{ 0338 /// Clone the emitter 0339 /// 0340 /// The emitter can only be cloned when it is mutable. The emitter calls 0341 /// into C++ code which may call into Rust again. If emmitting is possible 0342 /// from immutable structures, that might lead to access to a mutable 0343 /// reference. That is undefined behaviour and forbidden. 0344 pub fn clone(&mut self) -> {0}Emitter {{ 0345 {0}Emitter {{ 0346 qobject: self.qobject.clone(),", 0347 o.name 0348 )?; 0349 for (name, p) in &o.properties { 0350 if p.is_object() { 0351 continue; 0352 } 0353 writeln!( 0354 r, 0355 " {}_changed: self.{0}_changed,", 0356 snake_case(name), 0357 )?; 0358 } 0359 if o.object_type != ObjectType::Object { 0360 writeln!(r, " new_data_ready: self.new_data_ready,")?; 0361 } 0362 writeln!( 0363 r, 0364 " }} 0365 }} 0366 fn clear(&self) {{ 0367 let n: *const {0}QObject = null(); 0368 self.qobject.store(n as *mut {0}QObject, Ordering::SeqCst); 0369 }}", 0370 o.name 0371 )?; 0372 0373 for (name, p) in &o.properties { 0374 if p.is_object() { 0375 continue; 0376 } 0377 writeln!( 0378 r, 0379 " pub fn {}_changed(&mut self) {{ 0380 let ptr = self.qobject.load(Ordering::SeqCst); 0381 if !ptr.is_null() {{ 0382 (self.{0}_changed)(ptr); 0383 }} 0384 }}", 0385 snake_case(name) 0386 )?; 0387 } 0388 0389 for (name, f) in &o.functions { 0390 // Generate 'invoke_*' methods to call functions from the 0391 // event loop using QMetaObject::invokeMethod. Only 0392 // implemented for functions with no arguments and void return. 0393 if f.arguments.is_empty() && f.return_type == SimpleType::Void { 0394 writeln!( 0395 r, 0396 " /// Invoke the `{0}` function on the QObject's event loop. 0397 pub fn invoke_{0}(&mut self) {{ 0398 let ptr = self.qobject.load(Ordering::SeqCst); 0399 if !ptr.is_null() {{ 0400 unsafe {{ 0401 qmetaobject__invokeMethod__0( 0402 ptr as *const std::ffi::c_void, 0403 std::ffi::CStr::from_bytes_with_nul_unchecked(b\"{0}\\0\").as_ptr() 0404 ); 0405 }} 0406 }} 0407 }}", 0408 snake_case(name) 0409 )?; 0410 } 0411 } 0412 0413 if o.object_type == ObjectType::List { 0414 writeln!( 0415 r, 0416 " pub fn new_data_ready(&mut self) {{ 0417 let ptr = self.qobject.load(Ordering::SeqCst); 0418 if !ptr.is_null() {{ 0419 (self.new_data_ready)(ptr); 0420 }} 0421 }}" 0422 )?; 0423 } else if o.object_type == ObjectType::Tree { 0424 writeln!( 0425 r, 0426 " pub fn new_data_ready(&mut self, item: Option<usize>) {{ 0427 let ptr = self.qobject.load(Ordering::SeqCst); 0428 if !ptr.is_null() {{ 0429 (self.new_data_ready)(ptr, item.into()); 0430 }} 0431 }}" 0432 )?; 0433 } 0434 0435 let mut model_struct = String::new(); 0436 if o.object_type != ObjectType::Object { 0437 let type_ = if o.object_type == ObjectType::List { 0438 "List" 0439 } else { 0440 "Tree" 0441 }; 0442 model_struct = format!(", model: {}{}", o.name, type_); 0443 let mut index = ""; 0444 let mut index_decl = ""; 0445 let mut index_c_decl = ""; 0446 let mut dest = ""; 0447 let mut dest_decl = ""; 0448 let mut dest_c_decl = ""; 0449 if o.object_type == ObjectType::Tree { 0450 index_decl = " index: Option<usize>,"; 0451 index_c_decl = " index: COption<usize>,"; 0452 index = " index.into(),"; 0453 dest_decl = " dest: Option<usize>,"; 0454 dest_c_decl = " dest: COption<usize>,"; 0455 dest = " dest.into(),"; 0456 } 0457 writeln!( 0458 r, 0459 "}} 0460 0461 #[derive(Clone)] 0462 pub struct {0}{1} {{ 0463 qobject: *mut {0}QObject, 0464 layout_about_to_be_changed: extern fn(*mut {0}QObject), 0465 layout_changed: extern fn(*mut {0}QObject), 0466 data_changed: extern fn(*mut {0}QObject, usize, usize), 0467 begin_reset_model: extern fn(*mut {0}QObject), 0468 end_reset_model: extern fn(*mut {0}QObject), 0469 begin_insert_rows: extern fn(*mut {0}QObject,{4} usize, usize), 0470 end_insert_rows: extern fn(*mut {0}QObject), 0471 begin_move_rows: extern fn(*mut {0}QObject,{4} usize, usize,{7} usize), 0472 end_move_rows: extern fn(*mut {0}QObject), 0473 begin_remove_rows: extern fn(*mut {0}QObject,{4} usize, usize), 0474 end_remove_rows: extern fn(*mut {0}QObject), 0475 }} 0476 0477 impl {0}{1} {{ 0478 pub fn layout_about_to_be_changed(&mut self) {{ 0479 (self.layout_about_to_be_changed)(self.qobject); 0480 }} 0481 pub fn layout_changed(&mut self) {{ 0482 (self.layout_changed)(self.qobject); 0483 }} 0484 pub fn data_changed(&mut self, first: usize, last: usize) {{ 0485 (self.data_changed)(self.qobject, first, last); 0486 }} 0487 pub fn begin_reset_model(&mut self) {{ 0488 (self.begin_reset_model)(self.qobject); 0489 }} 0490 pub fn end_reset_model(&mut self) {{ 0491 (self.end_reset_model)(self.qobject); 0492 }} 0493 pub fn begin_insert_rows(&mut self,{2} first: usize, last: usize) {{ 0494 (self.begin_insert_rows)(self.qobject,{3} first, last); 0495 }} 0496 pub fn end_insert_rows(&mut self) {{ 0497 (self.end_insert_rows)(self.qobject); 0498 }} 0499 pub fn begin_move_rows(&mut self,{2} first: usize, last: usize,{5} destination: usize) {{ 0500 (self.begin_move_rows)(self.qobject,{3} first, last,{6} destination); 0501 }} 0502 pub fn end_move_rows(&mut self) {{ 0503 (self.end_move_rows)(self.qobject); 0504 }} 0505 pub fn begin_remove_rows(&mut self,{2} first: usize, last: usize) {{ 0506 (self.begin_remove_rows)(self.qobject,{3} first, last); 0507 }} 0508 pub fn end_remove_rows(&mut self) {{ 0509 (self.end_remove_rows)(self.qobject); 0510 }}", 0511 o.name, type_, index_decl, index, index_c_decl, dest_decl, dest, dest_c_decl 0512 )?; 0513 } 0514 0515 write!( 0516 r, 0517 "}} 0518 0519 pub trait {}Trait {{ 0520 fn new(emit: {0}Emitter{}", 0521 o.name, model_struct 0522 )?; 0523 for (name, p) in &o.properties { 0524 if p.is_object() { 0525 write!(r, ",\n {}: {}", snake_case(name), p.type_name())?; 0526 } 0527 } 0528 writeln!( 0529 r, 0530 ") -> Self; 0531 fn emit(&mut self) -> &mut {}Emitter;", 0532 o.name 0533 )?; 0534 for (name, p) in &o.properties { 0535 let lc = snake_case(name).to_lowercase(); 0536 if p.is_object() { 0537 writeln!(r, " fn {}(&self) -> &{};", lc, rust_type(p))?; 0538 writeln!(r, " fn {}_mut(&mut self) -> &mut {};", lc, rust_type(p))?; 0539 } else { 0540 if p.rust_by_function { 0541 write!( 0542 r, 0543 " fn {}<F>(&self, getter: F) where F: FnOnce({});", 0544 lc, 0545 rust_return_type(p) 0546 )?; 0547 } else { 0548 writeln!(r, " fn {}(&self) -> {};", lc, rust_return_type(p))?; 0549 } 0550 if p.write { 0551 if p.type_name() == "QByteArray" { 0552 if p.optional { 0553 writeln!(r, " fn set_{}(&mut self, value: Option<&[u8]>);", lc)?; 0554 } else { 0555 writeln!(r, " fn set_{}(&mut self, value: &[u8]);", lc)?; 0556 } 0557 } else { 0558 writeln!(r, " fn set_{}(&mut self, value: {});", lc, rust_type(p))?; 0559 } 0560 } 0561 } 0562 } 0563 for (name, f) in &o.functions { 0564 let lc = snake_case(name); 0565 let mut arg_list = String::new(); 0566 if !f.arguments.is_empty() { 0567 for a in &f.arguments { 0568 let t = if a.argument_type.name() == "QByteArray" { 0569 "&[u8]" 0570 } else { 0571 a.argument_type.rust_type() 0572 }; 0573 arg_list.push_str(&format!(", {}: {}", a.name, t)); 0574 } 0575 } 0576 writeln!( 0577 r, 0578 " fn {}(&{}self{}) -> {};", 0579 lc, 0580 if f.mutable { "mut " } else { "" }, 0581 arg_list, 0582 f.return_type.rust_type() 0583 )?; 0584 } 0585 if o.object_type == ObjectType::List { 0586 writeln!( 0587 r, 0588 " fn row_count(&self) -> usize; 0589 fn insert_rows(&mut self, _row: usize, _count: usize) -> bool {{ false }} 0590 fn remove_rows(&mut self, _row: usize, _count: usize) -> bool {{ false }} 0591 fn can_fetch_more(&self) -> bool {{ 0592 false 0593 }} 0594 fn fetch_more(&mut self) {{}} 0595 fn sort(&mut self, _: u8, _: SortOrder) {{}}" 0596 )?; 0597 } else if o.object_type == ObjectType::Tree { 0598 writeln!( 0599 r, 0600 " fn row_count(&self, _: Option<usize>) -> usize; 0601 fn can_fetch_more(&self, _: Option<usize>) -> bool {{ 0602 false 0603 }} 0604 fn fetch_more(&mut self, _: Option<usize>) {{}} 0605 fn sort(&mut self, _: u8, _: SortOrder) {{}} 0606 fn check_row(&self, index: usize, row: usize) -> Option<usize>; 0607 fn index(&self, item: Option<usize>, row: usize) -> usize; 0608 fn parent(&self, index: usize) -> Option<usize>; 0609 fn row(&self, index: usize) -> usize;" 0610 )?; 0611 } 0612 if o.object_type != ObjectType::Object { 0613 for (name, ip) in &o.item_properties { 0614 let name = snake_case(name); 0615 writeln!( 0616 r, 0617 " fn {}(&self, index: usize) -> {};", 0618 name, 0619 rust_return_type_(ip) 0620 )?; 0621 if ip.write { 0622 if ip.item_property_type.name() == "QByteArray" { 0623 if ip.optional { 0624 writeln!( 0625 r, 0626 " fn set_{}(&mut self, index: usize, _: Option<&[u8]>) -> bool;", 0627 name 0628 )?; 0629 } else { 0630 writeln!( 0631 r, 0632 " fn set_{}(&mut self, index: usize, _: &[u8]) -> bool;", 0633 name 0634 )?; 0635 } 0636 } else { 0637 writeln!( 0638 r, 0639 " fn set_{}(&mut self, index: usize, _: {}) -> bool;", 0640 name, 0641 rust_type_(ip) 0642 )?; 0643 } 0644 } 0645 } 0646 } 0647 writeln!( 0648 r, 0649 "}} 0650 0651 #[no_mangle] 0652 pub extern \"C\" fn {}_new(", 0653 lcname 0654 )?; 0655 r_constructor_args_decl(r, &lcname, o, conf)?; 0656 writeln!(r, ",\n) -> *mut {} {{", o.name)?; 0657 r_constructor_args(r, &lcname, o, conf)?; 0658 writeln!( 0659 r, 0660 " Box::into_raw(Box::new(d_{})) 0661 }} 0662 0663 #[no_mangle] 0664 pub unsafe extern \"C\" fn {0}_free(ptr: *mut {}) {{ 0665 Box::from_raw(ptr).emit().clear(); 0666 }}", 0667 lcname, o.name 0668 )?; 0669 0670 for (name, p) in &o.properties { 0671 let base = format!("{}_{}", lcname, snake_case(name)); 0672 if p.is_object() { 0673 writeln!( 0674 r, 0675 " 0676 #[no_mangle] 0677 pub unsafe extern \"C\" fn {}_get(ptr: *mut {}) -> *mut {} {{ 0678 (&mut *ptr).{}_mut() 0679 }}", 0680 base, 0681 o.name, 0682 rust_type(p), 0683 snake_case(name) 0684 )?; 0685 } else if p.is_complex() && !p.optional { 0686 if p.rust_by_function { 0687 writeln!( 0688 r, 0689 " 0690 #[no_mangle] 0691 pub unsafe extern \"C\" fn {}_get( 0692 ptr: *const {}, 0693 p: *mut {}, 0694 set: extern fn(*mut {2}, *const c_char, c_int), 0695 ) {{ 0696 let o = &*ptr; 0697 o.{}(|v| {{ 0698 let s: *const c_char = v.as_ptr() as *const c_char; 0699 set(p, s, to_c_int(v.len())); 0700 }}); 0701 }}", 0702 base, 0703 o.name, 0704 p.type_name(), 0705 snake_case(name) 0706 )?; 0707 } else { 0708 writeln!( 0709 r, 0710 " 0711 #[no_mangle] 0712 pub unsafe extern \"C\" fn {}_get( 0713 ptr: *const {}, 0714 p: *mut {}, 0715 set: extern fn(*mut {2}, *const c_char, c_int), 0716 ) {{ 0717 let o = &*ptr; 0718 let v = o.{}(); 0719 let s: *const c_char = v.as_ptr() as *const c_char; 0720 set(p, s, to_c_int(v.len())); 0721 }}", 0722 base, 0723 o.name, 0724 p.type_name(), 0725 snake_case(name) 0726 )?; 0727 } 0728 if p.write && p.type_name() == "QString" { 0729 writeln!( 0730 r, 0731 " 0732 #[no_mangle] 0733 pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: *const c_ushort, len: c_int) {{ 0734 let o = &mut *ptr; 0735 let mut s = String::new(); 0736 set_string_from_utf16(&mut s, v, len); 0737 o.set_{}(s); 0738 }}", 0739 base, 0740 o.name, 0741 snake_case(name) 0742 )?; 0743 } else if p.write { 0744 writeln!( 0745 r, 0746 " 0747 #[no_mangle] 0748 pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: *const c_char, len: c_int) {{ 0749 let o = &mut *ptr; 0750 let v = slice::from_raw_parts(v as *const u8, to_usize(len)); 0751 o.set_{}(v); 0752 }}", 0753 base, 0754 o.name, 0755 snake_case(name) 0756 )?; 0757 } 0758 } else if p.is_complex() { 0759 writeln!( 0760 r, 0761 " 0762 #[no_mangle] 0763 pub unsafe extern \"C\" fn {}_get( 0764 ptr: *const {}, 0765 p: *mut {}, 0766 set: extern fn(*mut {2}, *const c_char, c_int), 0767 ) {{ 0768 let o = &*ptr; 0769 let v = o.{}(); 0770 if let Some(v) = v {{ 0771 let s: *const c_char = v.as_ptr() as *const c_char; 0772 set(p, s, to_c_int(v.len())); 0773 }} 0774 }}", 0775 base, 0776 o.name, 0777 p.type_name(), 0778 snake_case(name) 0779 )?; 0780 if p.write && p.type_name() == "QString" { 0781 writeln!( 0782 r, 0783 " 0784 #[no_mangle] 0785 pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: *const c_ushort, len: c_int) {{ 0786 let o = &mut *ptr; 0787 let mut s = String::new(); 0788 set_string_from_utf16(&mut s, v, len); 0789 o.set_{}(Some(s)); 0790 }}", 0791 base, 0792 o.name, 0793 snake_case(name) 0794 )?; 0795 } else if p.write { 0796 writeln!( 0797 r, 0798 " 0799 #[no_mangle] 0800 pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: *const c_char, len: c_int) {{ 0801 let o = &mut *ptr; 0802 let v = slice::from_raw_parts(v as *const u8, to_usize(len)); 0803 o.set_{}(Some(v.into())); 0804 }}", 0805 base, 0806 o.name, 0807 snake_case(name) 0808 )?; 0809 } 0810 } else if p.optional { 0811 writeln!( 0812 r, 0813 " 0814 #[no_mangle] 0815 pub unsafe extern \"C\" fn {}_get(ptr: *const {}) -> COption<{}> {{ 0816 match (&*ptr).{}() {{ 0817 Some(value) => COption {{ data: value, some: true }}, 0818 None => COption {{ data: {2}::default(), some: false}} 0819 }} 0820 }}", 0821 base, 0822 o.name, 0823 p.property_type.rust_type(), 0824 snake_case(name) 0825 )?; 0826 if p.write { 0827 writeln!( 0828 r, 0829 " 0830 #[no_mangle] 0831 pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: {}) {{ 0832 (&mut *ptr).set_{}(Some(v)); 0833 }}", 0834 base, 0835 o.name, 0836 p.property_type.rust_type(), 0837 snake_case(name) 0838 )?; 0839 } 0840 } else { 0841 writeln!( 0842 r, 0843 " 0844 #[no_mangle] 0845 pub unsafe extern \"C\" fn {}_get(ptr: *const {}) -> {} {{ 0846 (&*ptr).{}() 0847 }}", 0848 base, 0849 o.name, 0850 rust_type(p), 0851 snake_case(name) 0852 )?; 0853 if p.write { 0854 writeln!( 0855 r, 0856 " 0857 #[no_mangle] 0858 pub unsafe extern \"C\" fn {}_set(ptr: *mut {}, v: {}) {{ 0859 (&mut *ptr).set_{}(v); 0860 }}", 0861 base, 0862 o.name, 0863 rust_type(p), 0864 snake_case(name) 0865 )?; 0866 } 0867 } 0868 if p.write && p.optional { 0869 writeln!( 0870 r, 0871 " 0872 #[no_mangle] 0873 pub unsafe extern \"C\" fn {}_set_none(ptr: *mut {}) {{ 0874 let o = &mut *ptr; 0875 o.set_{}(None); 0876 }}", 0877 base, 0878 o.name, 0879 snake_case(name) 0880 )?; 0881 } 0882 } 0883 for f in &o.functions { 0884 write_function(r, f, &lcname, o)?; 0885 } 0886 if o.object_type == ObjectType::List { 0887 writeln!( 0888 r, 0889 " 0890 #[no_mangle] 0891 pub unsafe extern \"C\" fn {1}_row_count(ptr: *const {0}) -> c_int {{ 0892 to_c_int((&*ptr).row_count()) 0893 }} 0894 #[no_mangle] 0895 pub unsafe extern \"C\" fn {1}_insert_rows(ptr: *mut {0}, row: c_int, count: c_int) -> bool {{ 0896 (&mut *ptr).insert_rows(to_usize(row), to_usize(count)) 0897 }} 0898 #[no_mangle] 0899 pub unsafe extern \"C\" fn {1}_remove_rows(ptr: *mut {0}, row: c_int, count: c_int) -> bool {{ 0900 (&mut *ptr).remove_rows(to_usize(row), to_usize(count)) 0901 }} 0902 #[no_mangle] 0903 pub unsafe extern \"C\" fn {1}_can_fetch_more(ptr: *const {0}) -> bool {{ 0904 (&*ptr).can_fetch_more() 0905 }} 0906 #[no_mangle] 0907 pub unsafe extern \"C\" fn {1}_fetch_more(ptr: *mut {0}) {{ 0908 (&mut *ptr).fetch_more() 0909 }} 0910 #[no_mangle] 0911 pub unsafe extern \"C\" fn {1}_sort( 0912 ptr: *mut {0}, 0913 column: u8, 0914 order: SortOrder, 0915 ) {{ 0916 (&mut *ptr).sort(column, order) 0917 }}", 0918 o.name, lcname 0919 )?; 0920 } else if o.object_type == ObjectType::Tree { 0921 writeln!( 0922 r, 0923 " 0924 #[no_mangle] 0925 pub unsafe extern \"C\" fn {1}_row_count( 0926 ptr: *const {0}, 0927 index: COption<usize>, 0928 ) -> c_int {{ 0929 to_c_int((&*ptr).row_count(index.into())) 0930 }} 0931 #[no_mangle] 0932 pub unsafe extern \"C\" fn {1}_can_fetch_more( 0933 ptr: *const {0}, 0934 index: COption<usize>, 0935 ) -> bool {{ 0936 (&*ptr).can_fetch_more(index.into()) 0937 }} 0938 #[no_mangle] 0939 pub unsafe extern \"C\" fn {1}_fetch_more(ptr: *mut {0}, index: COption<usize>) {{ 0940 (&mut *ptr).fetch_more(index.into()) 0941 }} 0942 #[no_mangle] 0943 pub unsafe extern \"C\" fn {1}_sort( 0944 ptr: *mut {0}, 0945 column: u8, 0946 order: SortOrder 0947 ) {{ 0948 (&mut *ptr).sort(column, order) 0949 }} 0950 #[no_mangle] 0951 pub unsafe extern \"C\" fn {1}_check_row( 0952 ptr: *const {0}, 0953 index: usize, 0954 row: c_int, 0955 ) -> COption<usize> {{ 0956 (&*ptr).check_row(index, to_usize(row)).into() 0957 }} 0958 #[no_mangle] 0959 pub unsafe extern \"C\" fn {1}_index( 0960 ptr: *const {0}, 0961 index: COption<usize>, 0962 row: c_int, 0963 ) -> usize {{ 0964 (&*ptr).index(index.into(), to_usize(row)) 0965 }} 0966 #[no_mangle] 0967 pub unsafe extern \"C\" fn {1}_parent(ptr: *const {0}, index: usize) -> QModelIndex {{ 0968 if let Some(parent) = (&*ptr).parent(index) {{ 0969 QModelIndex {{ 0970 row: to_c_int((&*ptr).row(parent)), 0971 internal_id: parent, 0972 }} 0973 }} else {{ 0974 QModelIndex {{ 0975 row: -1, 0976 internal_id: 0, 0977 }} 0978 }} 0979 }} 0980 #[no_mangle] 0981 pub unsafe extern \"C\" fn {1}_row(ptr: *const {0}, index: usize) -> c_int {{ 0982 to_c_int((&*ptr).row(index)) 0983 }}", 0984 o.name, lcname 0985 )?; 0986 } 0987 if o.object_type != ObjectType::Object { 0988 let (index_decl, index) = if o.object_type == ObjectType::Tree { 0989 (", index: usize", "index") 0990 } else { 0991 (", row: c_int", "to_usize(row)") 0992 }; 0993 for (name, ip) in &o.item_properties { 0994 if ip.is_complex() && !ip.optional { 0995 writeln!( 0996 r, 0997 " 0998 #[no_mangle] 0999 pub unsafe extern \"C\" fn {}_data_{}( 1000 ptr: *const {}{}, 1001 d: *mut {}, 1002 set: extern fn(*mut {4}, *const c_char, len: c_int), 1003 ) {{ 1004 let o = &*ptr; 1005 let data = o.{1}({}); 1006 let s: *const c_char = data.as_ptr() as *const c_char; 1007 set(d, s, to_c_int(data.len())); 1008 }}", 1009 lcname, 1010 snake_case(name), 1011 o.name, 1012 index_decl, 1013 ip.type_name(), 1014 index 1015 )?; 1016 } else if ip.is_complex() { 1017 writeln!( 1018 r, 1019 " 1020 #[no_mangle] 1021 pub unsafe extern \"C\" fn {}_data_{}( 1022 ptr: *const {}{}, 1023 d: *mut {}, 1024 set: extern fn(*mut {4}, *const c_char, len: c_int), 1025 ) {{ 1026 let o = &*ptr; 1027 let data = o.{1}({}); 1028 if let Some(data) = data {{ 1029 let s: *const c_char = data.as_ptr() as *const c_char; 1030 set(d, s, to_c_int(data.len())); 1031 }} 1032 }}", 1033 lcname, 1034 snake_case(name), 1035 o.name, 1036 index_decl, 1037 ip.type_name(), 1038 index 1039 )?; 1040 } else { 1041 writeln!( 1042 r, 1043 " 1044 #[no_mangle] 1045 pub unsafe extern \"C\" fn {}_data_{}(ptr: *const {}{}) -> {} {{ 1046 let o = &*ptr; 1047 o.{1}({}){} 1048 }}", 1049 lcname, 1050 snake_case(name), 1051 o.name, 1052 index_decl, 1053 rust_c_type(ip), 1054 index, 1055 if ip.optional { ".into()" } else { "" } 1056 )?; 1057 } 1058 if ip.write { 1059 let val = if ip.optional { "Some(v)" } else { "v" }; 1060 if ip.type_name() == "QString" { 1061 writeln!( 1062 r, 1063 " 1064 #[no_mangle] 1065 pub unsafe extern \"C\" fn {}_set_data_{}( 1066 ptr: *mut {}{}, 1067 s: *const c_ushort, len: c_int, 1068 ) -> bool {{ 1069 let o = &mut *ptr; 1070 let mut v = String::new(); 1071 set_string_from_utf16(&mut v, s, len); 1072 o.set_{1}({}, {}) 1073 }}", 1074 lcname, 1075 snake_case(name), 1076 o.name, 1077 index_decl, 1078 index, 1079 val 1080 )?; 1081 } else if ip.type_name() == "QByteArray" { 1082 writeln!( 1083 r, 1084 " 1085 #[no_mangle] 1086 pub unsafe extern \"C\" fn {}_set_data_{}( 1087 ptr: *mut {}{}, 1088 s: *const c_char, len: c_int, 1089 ) -> bool {{ 1090 let o = &mut *ptr; 1091 let slice = ::std::slice::from_raw_parts(s as *const u8, to_usize(len)); 1092 o.set_{1}({}, {}) 1093 }}", 1094 lcname, 1095 snake_case(name), 1096 o.name, 1097 index_decl, 1098 index, 1099 if ip.optional { "Some(slice)" } else { "slice" } 1100 )?; 1101 } else { 1102 let type_ = ip.item_property_type.rust_type(); 1103 writeln!( 1104 r, 1105 " 1106 #[no_mangle] 1107 pub unsafe extern \"C\" fn {}_set_data_{}( 1108 ptr: *mut {}{}, 1109 v: {}, 1110 ) -> bool {{ 1111 (&mut *ptr).set_{1}({}, {}) 1112 }}", 1113 lcname, 1114 snake_case(name), 1115 o.name, 1116 index_decl, 1117 type_, 1118 index, 1119 val 1120 )?; 1121 } 1122 } 1123 if ip.write && ip.optional { 1124 writeln!( 1125 r, 1126 " 1127 #[no_mangle] 1128 pub unsafe extern \"C\" fn {}_set_data_{}_none(ptr: *mut {}{}) -> bool {{ 1129 (&mut *ptr).set_{1}({}, None) 1130 }}", 1131 lcname, 1132 snake_case(name), 1133 o.name, 1134 index_decl, 1135 index 1136 )?; 1137 } 1138 } 1139 } 1140 Ok(()) 1141 } 1142 1143 fn write_rust_types(conf: &Config, r: &mut Vec<u8>) -> Result<()> { 1144 let mut has_option = false; 1145 let mut has_string = false; 1146 let mut has_byte_array = false; 1147 let mut has_list_or_tree = false; 1148 1149 for o in conf.objects.values() { 1150 has_list_or_tree |= o.object_type != ObjectType::Object; 1151 for p in o.properties.values() { 1152 has_option |= p.optional; 1153 has_string |= p.property_type == Type::Simple(SimpleType::QString); 1154 has_byte_array |= p.property_type == Type::Simple(SimpleType::QByteArray); 1155 } 1156 for p in o.item_properties.values() { 1157 has_option |= p.optional; 1158 has_string |= p.item_property_type == SimpleType::QString; 1159 has_byte_array |= p.item_property_type == SimpleType::QByteArray; 1160 } 1161 for f in o.functions.values() { 1162 has_string |= f.return_type == SimpleType::QString; 1163 has_byte_array |= f.return_type == SimpleType::QByteArray; 1164 for a in &f.arguments { 1165 has_string |= a.argument_type == SimpleType::QString; 1166 has_byte_array |= a.argument_type == SimpleType::QByteArray; 1167 } 1168 } 1169 } 1170 1171 if has_option || has_list_or_tree { 1172 writeln!( 1173 r, 1174 " 1175 1176 #[repr(C)] 1177 pub struct COption<T> {{ 1178 data: T, 1179 some: bool, 1180 }} 1181 1182 impl<T> COption<T> {{ 1183 #![allow(dead_code)] 1184 fn into(self) -> Option<T> {{ 1185 if self.some {{ 1186 Some(self.data) 1187 }} else {{ 1188 None 1189 }} 1190 }} 1191 }} 1192 1193 impl<T> From<Option<T>> for COption<T> 1194 where 1195 T: Default, 1196 {{ 1197 fn from(t: Option<T>) -> COption<T> {{ 1198 if let Some(v) = t {{ 1199 COption {{ 1200 data: v, 1201 some: true, 1202 }} 1203 }} else {{ 1204 COption {{ 1205 data: T::default(), 1206 some: false, 1207 }} 1208 }} 1209 }} 1210 }}" 1211 )?; 1212 } 1213 if has_string { 1214 writeln!( 1215 r, 1216 " 1217 1218 pub enum QString {{}} 1219 1220 fn set_string_from_utf16(s: &mut String, str: *const c_ushort, len: c_int) {{ 1221 let utf16 = unsafe {{ slice::from_raw_parts(str, to_usize(len)) }}; 1222 let characters = decode_utf16(utf16.iter().cloned()) 1223 .map(|r| r.unwrap()); 1224 s.clear(); 1225 s.extend(characters); 1226 }} 1227 " 1228 )?; 1229 } 1230 if has_byte_array { 1231 writeln!( 1232 r, 1233 " 1234 1235 pub enum QByteArray {{}}" 1236 )?; 1237 } 1238 if has_list_or_tree { 1239 writeln!( 1240 r, 1241 " 1242 1243 #[repr(C)] 1244 #[derive(PartialEq, Eq, Debug)] 1245 pub enum SortOrder {{ 1246 Ascending = 0, 1247 Descending = 1, 1248 }} 1249 1250 #[repr(C)] 1251 pub struct QModelIndex {{ 1252 row: c_int, 1253 internal_id: usize, 1254 }}" 1255 )?; 1256 } 1257 1258 if has_string || has_byte_array || has_list_or_tree { 1259 writeln!( 1260 r, 1261 " 1262 1263 fn to_usize(n: c_int) -> usize {{ 1264 if n < 0 {{ 1265 panic!(\"Cannot cast {{}} to usize\", n); 1266 }} 1267 n as usize 1268 }} 1269 " 1270 )?; 1271 } 1272 1273 if has_string || has_byte_array || has_list_or_tree { 1274 writeln!( 1275 r, 1276 " 1277 fn to_c_int(n: usize) -> c_int {{ 1278 if n > c_int::max_value() as usize {{ 1279 panic!(\"Cannot cast {{}} to c_int\", n); 1280 }} 1281 n as c_int 1282 }} 1283 " 1284 )?; 1285 } 1286 Ok(()) 1287 } 1288 1289 pub fn write_interface(conf: &Config) -> Result<()> { 1290 let mut r = Vec::new(); 1291 writeln!( 1292 r, 1293 "/* generated by rust_qt_binding_generator */ 1294 use libc::{{c_char, c_ushort, c_int}}; 1295 use std::slice; 1296 use std::char::decode_utf16; 1297 1298 use std::sync::Arc; 1299 use std::sync::atomic::{{AtomicPtr, Ordering}}; 1300 use std::ptr::null; 1301 1302 use {}{}::*;", 1303 get_module_prefix(conf), 1304 conf.rust.implementation_module 1305 )?; 1306 1307 writeln!( 1308 r, 1309 " 1310 extern \"C\" {{ 1311 pub fn qmetaobject__invokeMethod__0(obj: *const std::ffi::c_void, member: *const c_char); 1312 }} 1313 " 1314 )?; 1315 1316 write_rust_types(conf, &mut r)?; 1317 1318 for object in conf.objects.values() { 1319 write_rust_interface_object(&mut r, object, conf)?; 1320 } 1321 let mut file = conf 1322 .config_file 1323 .parent() 1324 .unwrap() 1325 .join(&conf.rust.dir) 1326 .join("src") 1327 .join(&conf.rust.interface_module); 1328 file.set_extension("rs"); 1329 write_if_different(file, &r) 1330 } 1331 1332 fn write_rust_implementation_object(r: &mut Vec<u8>, o: &Object) -> Result<()> { 1333 if o.object_type != ObjectType::Object { 1334 writeln!(r, "#[derive(Default, Clone)]")?; 1335 writeln!(r, "struct {}Item {{", o.name)?; 1336 for (name, ip) in &o.item_properties { 1337 let lc = snake_case(name); 1338 if ip.optional { 1339 writeln!( 1340 r, 1341 " {}: Option<{}>,", 1342 lc, 1343 ip.item_property_type.rust_type() 1344 )?; 1345 } else { 1346 writeln!(r, " {}: {},", lc, ip.item_property_type.rust_type())?; 1347 } 1348 } 1349 writeln!(r, "}}\n")?; 1350 } 1351 let mut model_struct = String::new(); 1352 writeln!(r, "pub struct {} {{\n emit: {0}Emitter,", o.name)?; 1353 if o.object_type == ObjectType::List { 1354 model_struct = format!(", model: {}List", o.name); 1355 writeln!(r, " model: {}List,", o.name)?; 1356 } else if o.object_type == ObjectType::Tree { 1357 model_struct = format!(", model: {}Tree", o.name); 1358 writeln!(r, " model: {}Tree,", o.name)?; 1359 } 1360 for (name, p) in &o.properties { 1361 let lc = snake_case(name); 1362 writeln!(r, " {}: {},", lc, rust_type(p))?; 1363 } 1364 if o.object_type != ObjectType::Object { 1365 writeln!(r, " list: Vec<{}Item>,", o.name)?; 1366 } 1367 writeln!(r, "}}\n")?; 1368 for (name, p) in &o.properties { 1369 if p.is_object() { 1370 model_struct += &format!(", {}: {}", name, p.type_name()); 1371 } 1372 } 1373 writeln!( 1374 r, 1375 "impl {}Trait for {0} {{ 1376 fn new(emit: {0}Emitter{}) -> {0} {{ 1377 {0} {{ 1378 emit,", 1379 o.name, model_struct 1380 )?; 1381 if o.object_type != ObjectType::Object { 1382 writeln!(r, " model,")?; 1383 writeln!(r, " list: Vec::new(),")?; 1384 } 1385 for (name, p) in &o.properties { 1386 let lc = snake_case(name); 1387 if p.is_object() { 1388 writeln!(r, " {},", lc)?; 1389 } else { 1390 writeln!(r, " {}: {},", lc, rust_type_init(p))?; 1391 } 1392 } 1393 writeln!( 1394 r, 1395 " }} 1396 }} 1397 fn emit(&mut self) -> &mut {}Emitter {{ 1398 &self.emit 1399 }}", 1400 o.name 1401 )?; 1402 for (name, p) in &o.properties { 1403 let lc = snake_case(name); 1404 if p.is_object() { 1405 writeln!( 1406 r, 1407 " fn {}(&self) -> &{} {{ 1408 &self.{0} 1409 }} 1410 fn {0}_mut(&mut self) -> &mut {1} {{ 1411 &mut self.{0} 1412 }}", 1413 lc, 1414 rust_return_type(p) 1415 )?; 1416 } else if p.rust_by_function { 1417 writeln!( 1418 r, 1419 " fn {}<F>(&self, getter: F) 1420 where 1421 F: FnOnce({}), 1422 {{ 1423 getter(&self.{0}) 1424 }}", 1425 lc, 1426 rust_return_type(p) 1427 )?; 1428 } else { 1429 writeln!(r, " fn {}(&self) -> {} {{", lc, rust_return_type(p))?; 1430 if p.is_complex() { 1431 if p.optional { 1432 writeln!(r, " self.{}.as_ref().map(|p| &p[..])", lc)?; 1433 } else { 1434 writeln!(r, " &self.{}", lc)?; 1435 } 1436 } else { 1437 writeln!(r, " self.{}", lc)?; 1438 } 1439 writeln!(r, " }}")?; 1440 } 1441 if !p.is_object() && p.write { 1442 let bytearray = p.property_type == Type::Simple(SimpleType::QByteArray); 1443 let (t, v) = if bytearray && p.optional { 1444 ("Option<&[u8]>".to_string(), ".map(|v| v.to_vec())") 1445 } else if bytearray { 1446 ("&[u8]".to_string(), ".to_vec()") 1447 } else { 1448 (rust_type(p), "") 1449 }; 1450 writeln!( 1451 r, 1452 " fn set_{}(&mut self, value: {}) {{ 1453 self.{0} = value{}; 1454 self.emit.{0}_changed(); 1455 }}", 1456 lc, t, v 1457 )?; 1458 } 1459 } 1460 if o.object_type == ObjectType::List { 1461 writeln!( 1462 r, 1463 " fn row_count(&self) -> usize {{\n self.list.len()\n }}" 1464 )?; 1465 } else if o.object_type == ObjectType::Tree { 1466 writeln!( 1467 r, 1468 " fn row_count(&self, item: Option<usize>) -> usize {{ 1469 self.list.len() 1470 }} 1471 fn index(&self, item: Option<usize>, row: usize) -> usize {{ 1472 0 1473 }} 1474 fn parent(&self, index: usize) -> Option<usize> {{ 1475 None 1476 }} 1477 fn row(&self, index: usize) -> usize {{ 1478 index 1479 }} 1480 fn check_row(&self, index: usize, _row: usize) -> Option<usize> {{ 1481 if index < self.list.len() {{ 1482 Some(index) 1483 }} else {{ 1484 None 1485 }} 1486 }}" 1487 )?; 1488 } 1489 if o.object_type != ObjectType::Object { 1490 for (name, ip) in &o.item_properties { 1491 let lc = snake_case(name); 1492 writeln!( 1493 r, 1494 " fn {}(&self, index: usize) -> {} {{", 1495 lc, 1496 rust_return_type_(ip) 1497 )?; 1498 if ip.is_complex() && ip.optional { 1499 writeln!( 1500 r, 1501 " self.list[index].{}.as_ref().map(|v| &v[..])", 1502 lc 1503 )?; 1504 } else if ip.is_complex() { 1505 writeln!(r, " &self.list[index].{}", lc)?; 1506 } else { 1507 writeln!(r, " self.list[index].{}", lc)?; 1508 } 1509 writeln!(r, " }}")?; 1510 let bytearray = ip.item_property_type == SimpleType::QByteArray; 1511 if ip.write && bytearray && ip.optional { 1512 writeln!( 1513 r, 1514 " fn set_{}(&mut self, index: usize, v: Option<&[u8]>) -> bool {{ 1515 self.list[index].{0} = v.map(|v| v.to_vec()); 1516 true 1517 }}", 1518 lc 1519 )?; 1520 } else if ip.write && bytearray { 1521 writeln!( 1522 r, 1523 " fn set_{}(&mut self, index: usize, v: &[u8]) -> bool {{ 1524 self.list[index].{0} = v.to_vec(); 1525 true 1526 }}", 1527 lc 1528 )?; 1529 } else if ip.write { 1530 writeln!( 1531 r, 1532 " fn set_{}(&mut self, index: usize, v: {}) -> bool {{ 1533 self.list[index].{0} = v; 1534 true 1535 }}", 1536 lc, 1537 rust_type_(ip) 1538 )?; 1539 } 1540 } 1541 } 1542 writeln!(r, "}}") 1543 } 1544 1545 pub fn write_implementation(conf: &Config) -> Result<()> { 1546 let mut file = conf 1547 .config_file 1548 .parent() 1549 .unwrap() 1550 .join(&conf.rust.dir) 1551 .join("src") 1552 .join(&conf.rust.implementation_module); 1553 if !conf.overwrite_implementation && file.exists() { 1554 return Ok(()); 1555 } 1556 file.set_extension("rs"); 1557 if !conf.overwrite_implementation && file.exists() { 1558 return Ok(()); 1559 } 1560 let mut r = Vec::new(); 1561 writeln!( 1562 r, 1563 "#![allow(unused_imports)] 1564 #![allow(unused_variables)] 1565 #![allow(dead_code)] 1566 #![allow(unused_unit)] 1567 use {}{}::*; 1568 ", 1569 get_module_prefix(conf), 1570 conf.rust.interface_module 1571 )?; 1572 1573 for object in conf.objects.values() { 1574 write_rust_implementation_object(&mut r, object)?; 1575 } 1576 write_if_different(file, &r) 1577 } 1578 1579 /// Inspects the rust edition of the target crate to decide how the module 1580 /// imports should be written. 1581 /// 1582 /// As of Rust 2018, modules inside the crate should be prefixed with `crate::`. 1583 /// Prior to the 2018 edition, crate-local modules could be imported without 1584 /// this prefix. 1585 fn get_module_prefix(conf: &Config) -> &'static str { 1586 match conf.rust_edition { 1587 RustEdition::Rust2015 => "", 1588 _ => "crate::" 1589 } 1590 }