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 { pub mod serde_test {
use pyo3::prelude::*; use pyo3::prelude::*;
use quick_xml::de::from_str; 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::se::to_string;
use quick_xml::Writer; use quick_xml::writer::Writer;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fs; use std::fs;
use std::io::Cursor;
type IdType = i64; type IdType = i64;
@ -309,6 +312,8 @@ pub mod serde_test {
pub connections: Connections, pub connections: Connections,
#[serde(rename = "DisconnectedParts")] #[serde(rename = "DisconnectedParts")]
pub disconnected_parts: Option<DisconnectedParts>, pub disconnected_parts: Option<DisconnectedParts>,
#[serde(rename = "Parts")]
pub parts: Parts,
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
@ -349,10 +354,16 @@ pub mod serde_test {
pub part: Vec<Part>, pub part: Vec<Part>,
} }
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Tank {
#[serde(rename = "@fuel")]
pub fuel: f64,
}
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Part { pub struct Part {
// #[serde(rename = "@Tank")] #[serde(rename = "Tank")]
// pub tank: Option<Tank>, pub tank: Option<Tank>,
// #[serde(rename = "@Engine")] // #[serde(rename = "@Engine")]
// pub engine: Option<Engine>, // pub engine: Option<Engine>,
// #[serde(rename = "@Pod")] // #[serde(rename = "@Pod")]
@ -399,11 +410,29 @@ pub mod serde_test {
pub deployed: Option<i8>, 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] #[pyfunction]
#[pyo3(name = "test_ship_read_and_write")] #[pyo3(name = "test_ship_read_and_write")]
pub fn test_ship_read_and_write(file_name: String) -> PyResult<()> { pub fn test_ship_read_and_write(file_name: String) -> PyResult<()> {
let file = fs::read_to_string(file_name).unwrap(); let file = fs::read_to_string(file_name).unwrap();
let ship: TestShip = from_str(&file).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(); let save_string = to_string(&ship).unwrap();
fs::write("./test-xml-rs.xml", save_string).unwrap(); fs::write("./test-xml-rs.xml", save_string).unwrap();
Ok(()) Ok(())

View File

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

View File

@ -681,10 +681,11 @@ pub mod sr1 {
pub struct SR1Ship { pub struct SR1Ship {
pub name: String, pub name: String,
pub description: String, pub description: String,
pub parts: Vec<SR1PartData>, pub version: i32,
pub connections: Vec<Connection>,
pub lift_off: bool, pub lift_off: bool,
pub touch_ground: bool, pub touch_ground: bool,
pub parts: Vec<SR1PartData>,
pub connections: Vec<Connection>,
pub disconnected: Option<Vec<(Vec<SR1PartData>, Option<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<()> { pub fn save(&self, file_name: String) -> Option<()> {
let raw_ship = self.to_raw_ship(); use quick_xml::events::{BytesEnd, BytesStart, Event};
raw_ship.save(file_name); 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(()) Some(())
} }
} }
@ -788,7 +854,7 @@ pub mod sr1 {
RawShip { RawShip {
parts: RawParts { parts }, parts: RawParts { parts },
connects: connections, connects: connections,
version: 1, version: self.version,
lift_off: bool_to_i8(self.lift_off), lift_off: bool_to_i8(self.lift_off),
touch_ground: bool_to_i8(self.touch_ground), touch_ground: bool_to_i8(self.touch_ground),
disconnected, disconnected,