add compat for DR rs

This commit is contained in:
shenjack 2023-06-25 19:31:48 +08:00
parent c447374629
commit 6efdaaa5bc
3 changed files with 105 additions and 9 deletions

View File

@ -289,10 +289,13 @@ pub mod console {
pub mod serde_test {
use pyo3::prelude::*;
use quick_xml::de::from_str;
use quick_xml::events::{BytesEnd, BytesStart, Event};
use quick_xml::reader::Reader;
use quick_xml::se::to_string;
use quick_xml::Writer;
use quick_xml::writer::Writer;
use serde::{Deserialize, Serialize};
use std::fs;
use std::io::Cursor;
type IdType = i64;
@ -309,6 +312,8 @@ pub mod serde_test {
pub connections: Connections,
#[serde(rename = "DisconnectedParts")]
pub disconnected_parts: Option<DisconnectedParts>,
#[serde(rename = "Parts")]
pub parts: Parts,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
@ -349,10 +354,16 @@ pub mod serde_test {
pub part: Vec<Part>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Tank {
#[serde(rename = "@fuel")]
pub fuel: f64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Part {
// #[serde(rename = "@Tank")]
// pub tank: Option<Tank>,
#[serde(rename = "Tank")]
pub tank: Option<Tank>,
// #[serde(rename = "@Engine")]
// pub engine: Option<Engine>,
// #[serde(rename = "@Pod")]
@ -399,11 +410,29 @@ pub mod serde_test {
pub deployed: Option<i8>,
}
pub fn writer_write_test(ship_data: &TestShip) -> String {
let mut writer: Writer<Cursor<Vec<u8>>> = Writer::new(Cursor::new(Vec::new()));
// ship attr
let mut ship_elem = BytesStart::new("Ship");
ship_elem.push_attribute(("version", ship_data.version.to_string().as_str()));
ship_elem.push_attribute(("liftedOff", ship_data.lift_off.to_string().as_str()));
ship_elem.push_attribute(("touchingGround", ship_data.touching_ground.to_string().as_str()));
writer.write_event(Event::Start(ship_elem)).unwrap();
writer.write_event(Event::End(BytesEnd::new("Ship"))).unwrap();
let result: Vec<u8> = writer.into_inner().into_inner();
return String::from_utf8(result).unwrap();
}
#[pyfunction]
#[pyo3(name = "test_ship_read_and_write")]
pub fn test_ship_read_and_write(file_name: String) -> PyResult<()> {
let file = fs::read_to_string(file_name).unwrap();
let ship: TestShip = from_str(&file).unwrap();
let writer_string = writer_write_test(&ship);
fs::write("./writer-test.xml", writer_string).unwrap();
let save_string = to_string(&ship).unwrap();
fs::write("./test-xml-rs.xml", save_string).unwrap();
Ok(())

View File

@ -23,7 +23,7 @@ pub mod part_list {
}
#[allow(non_camel_case_types)]
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq)]
pub enum SR1PartTypeEnum {
pod,
detacher,
@ -576,6 +576,7 @@ pub mod ship {
SR1Ship {
name: name.unwrap_or("NewShip".to_string()),
description: "".to_string(),
version: self.version,
parts,
connections,
lift_off: i8_to_bool(self.lift_off.to_owned()),

View File

@ -681,10 +681,11 @@ pub mod sr1 {
pub struct SR1Ship {
pub name: String,
pub description: String,
pub parts: Vec<SR1PartData>,
pub connections: Vec<Connection>,
pub version: i32,
pub lift_off: bool,
pub touch_ground: bool,
pub parts: Vec<SR1PartData>,
pub connections: Vec<Connection>,
pub disconnected: Option<Vec<(Vec<SR1PartData>, Option<Vec<Connection>>)>>,
}
@ -737,8 +738,73 @@ pub mod sr1 {
}
pub fn save(&self, file_name: String) -> Option<()> {
let raw_ship = self.to_raw_ship();
raw_ship.save(file_name);
use quick_xml::events::{BytesEnd, BytesStart, Event};
use quick_xml::writer::Writer;
use std::fs;
use std::io::Cursor;
macro_rules! option_push_attr {
($elem: ident, $test_block: block, $push: expr) => {
if ($test_block) {
$elem.push_attribute($push);
}
};
}
fn write_parts(parts: &Vec<SR1PartData>, writer: &mut Writer<Cursor<Vec<u8>>>) -> () {
writer.write_event(Event::Start(BytesStart::new("Parts"))).unwrap();
for part in parts.iter() {
let mut part_attr = BytesStart::new("Part");
part_attr.push_attribute(("x", part.x.to_string().as_str()));
part_attr.push_attribute(("y", part.y.to_string().as_str()));
part_attr.push_attribute(("id", part.id.to_string().as_str()));
part_attr.push_attribute(("type", part.part_type_id.as_str()));
part_attr.push_attribute(("editorAngle", part.editor_angle.to_string().as_str()));
part_attr.push_attribute(("angle", part.angle.to_string().as_str()));
part_attr.push_attribute(("angleV", part.angle_v.to_string().as_str()));
part_attr.push_attribute(("flippedX", part.flip_x.to_string().as_str()));
part_attr.push_attribute(("flippedY", part.flip_y.to_string().as_str()));
part_attr.push_attribute(("activated", part.active.to_string().as_str()));
writer.write_event(Event::Start(part_attr)).unwrap();
match part.part_type {
SR1PartTypeEnum::tank | SR1PartTypeEnum::engine => {
let mut tank_attr = BytesStart::new({
if part.part_type == SR1PartTypeEnum::tank {
"Tank"
} else {
"Engine"
}
});
tank_attr.push_attribute(("fuel", part.attr.fuel.unwrap().to_string().as_str()));
writer.write_event(Event::Empty(tank_attr)).unwrap();
}
_ => {}
}
writer.write_event(Event::End(BytesEnd::new("Part"))).unwrap();
}
writer.write_event(Event::End(BytesEnd::new("Parts"))).unwrap();
}
fn write_data(data: &SR1Ship) -> String {
let mut writer: Writer<Cursor<Vec<u8>>> = Writer::new(Cursor::new(Vec::new()));
{
// ship attr
let mut ship_elem = BytesStart::new("Ship");
ship_elem.push_attribute(("version", data.version.to_string().as_str()));
ship_elem.push_attribute(("liftedOff", data.lift_off.to_string().as_str()));
ship_elem.push_attribute(("touchingGround", data.touch_ground.to_string().as_str()));
writer.write_event(Event::Start(ship_elem)).unwrap();
}
{
// Parts
write_parts(&data.parts, &mut writer);
}
writer.write_event(Event::End(BytesEnd::new("Ship"))).unwrap();
return String::from_utf8(writer.into_inner().into_inner()).unwrap();
}
fs::write(file_name, write_data(self)).unwrap();
Some(())
}
}
@ -788,7 +854,7 @@ pub mod sr1 {
RawShip {
parts: RawParts { parts },
connects: connections,
version: 1,
version: self.version,
lift_off: bool_to_i8(self.lift_off),
touch_ground: bool_to_i8(self.touch_ground),
disconnected,