Skip to main content

oxiphysics_python/serialization/
functions_2.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5#[allow(unused_imports)]
6use super::functions::*;
7
8use super::types::{SimulationCheckpoint, SimulationSnapshot};
9
10/// Serialize a complete simulation checkpoint from a snapshot.
11///
12/// Convenience wrapper around `SimulationCheckpoint::from_snapshot`.
13pub fn serialize_simulation_checkpoint(
14    snap: &SimulationSnapshot,
15    label: impl Into<String>,
16    step_count: u64,
17    timestamp: f64,
18) -> String {
19    let cp = SimulationCheckpoint::from_snapshot(snap, label, step_count, timestamp);
20    cp.to_json()
21}
22#[cfg(test)]
23mod json_checkpoint_tests {
24    use super::*;
25    use crate::serialization::BodyStateJson;
26    use crate::serialization::SimBodyState;
27    #[test]
28    fn test_serialize_body_state_json_roundtrip() {
29        let body = SimBodyState {
30            handle: 42,
31            position: [1.0, 2.0, 3.0],
32            velocity: [0.1, 0.2, 0.3],
33            orientation: [0.0, 0.0, 0.0, 1.0],
34            angular_velocity: [0.0; 3],
35            is_sleeping: false,
36            is_static: false,
37            tag: Some("ball".to_string()),
38        };
39        let json = serialize_body_state_json(&body);
40        let back = deserialize_body_state_json(&json).unwrap();
41        assert_eq!(back.handle, 42);
42        assert!((back.position[0] - 1.0).abs() < 1e-12);
43        assert_eq!(back.tag.as_deref(), Some("ball"));
44    }
45    #[test]
46    fn test_deserialize_body_state_json_invalid() {
47        let result = deserialize_body_state_json("not valid json");
48        assert!(result.is_err());
49    }
50    #[test]
51    fn test_body_state_json_schema_version() {
52        let body = SimBodyState::at_rest(0, [0.0; 3]);
53        let bsj = BodyStateJson::from_sim_body(&body);
54        assert_eq!(bsj.schema_version, "1.0.0");
55    }
56    #[test]
57    fn test_simulation_checkpoint_from_snapshot() {
58        let mut snap = SimulationSnapshot::empty();
59        snap.time = 5.0;
60        snap.bodies.push(SimBodyState::at_rest(0, [1.0, 2.0, 3.0]));
61        let cp = SimulationCheckpoint::from_snapshot(&snap, "test_checkpoint", 300, 12345.0);
62        assert_eq!(cp.label, "test_checkpoint");
63        assert!((cp.sim_time - 5.0).abs() < 1e-10);
64        assert_eq!(cp.step_count, 300);
65        assert_eq!(cp.body_count(), 1);
66    }
67    #[test]
68    fn test_simulation_checkpoint_json_roundtrip() {
69        let mut snap = SimulationSnapshot::empty();
70        snap.time = 2.5;
71        snap.gravity = [0.0, -9.81, 0.0];
72        snap.bodies.push(SimBodyState::at_rest(1, [0.0, 5.0, 0.0]));
73        let json = serialize_simulation_checkpoint(&snap, "save_1", 100, 0.0);
74        let cp = SimulationCheckpoint::from_json(&json).unwrap();
75        assert_eq!(cp.body_count(), 1);
76        assert!((cp.sim_time - 2.5).abs() < 1e-10);
77        let restored = cp.to_snapshot();
78        assert_eq!(restored.bodies.len(), 1);
79        assert!((restored.bodies[0].position[1] - 5.0).abs() < 1e-10);
80    }
81    #[test]
82    fn test_snapshot_diff_identical() {
83        let mut snap = SimulationSnapshot::empty();
84        snap.bodies.push(SimBodyState::at_rest(0, [1.0, 0.0, 0.0]));
85        snap.bodies.push(SimBodyState::at_rest(1, [2.0, 0.0, 0.0]));
86        let diff = snap.diff(&snap, 1e-6);
87        assert!(
88            diff.is_identical(),
89            "identical snapshots should yield empty diff"
90        );
91        assert!((diff.max_displacement).abs() < 1e-12);
92    }
93    #[test]
94    fn test_snapshot_diff_added_removed() {
95        let mut snap_a = SimulationSnapshot::empty();
96        snap_a.bodies.push(SimBodyState::at_rest(0, [0.0; 3]));
97        snap_a
98            .bodies
99            .push(SimBodyState::at_rest(1, [1.0, 0.0, 0.0]));
100        let mut snap_b = SimulationSnapshot::empty();
101        snap_b
102            .bodies
103            .push(SimBodyState::at_rest(1, [1.0, 0.0, 0.0]));
104        snap_b
105            .bodies
106            .push(SimBodyState::at_rest(2, [5.0, 0.0, 0.0]));
107        let diff = snap_a.diff(&snap_b, 1e-6);
108        assert_eq!(diff.removed.len(), 1);
109        assert!(diff.removed.contains(&0));
110        assert_eq!(diff.added.len(), 1);
111        assert!(diff.added.contains(&2));
112    }
113    #[test]
114    fn test_snapshot_diff_moved() {
115        let mut snap_a = SimulationSnapshot::empty();
116        snap_a.time = 0.0;
117        snap_a
118            .bodies
119            .push(SimBodyState::at_rest(0, [0.0, 0.0, 0.0]));
120        let mut snap_b = SimulationSnapshot::empty();
121        snap_b.time = 1.0;
122        let mut moved = SimBodyState::at_rest(0, [3.0, 4.0, 0.0]);
123        moved.velocity = [1.0, 0.0, 0.0];
124        snap_b.bodies.push(moved);
125        let diff = snap_a.diff(&snap_b, 1e-6);
126        assert_eq!(diff.moved.len(), 1);
127        assert_eq!(diff.moved[0], 0);
128        assert!(
129            (diff.max_displacement - 5.0).abs() < 1e-10,
130            "disp = {}",
131            diff.max_displacement
132        );
133        assert!((diff.time_delta - 1.0).abs() < 1e-10);
134    }
135    #[test]
136    fn test_snapshot_diff_change_count() {
137        let snap_a = SimulationSnapshot::empty();
138        let mut snap_b = SimulationSnapshot::empty();
139        snap_b.bodies.push(SimBodyState::at_rest(0, [0.0; 3]));
140        snap_b
141            .bodies
142            .push(SimBodyState::at_rest(1, [1.0, 0.0, 0.0]));
143        let diff = snap_a.diff(&snap_b, 1e-6);
144        assert_eq!(diff.change_count(), 2);
145        assert!(!diff.is_identical());
146    }
147    #[test]
148    fn test_checkpoint_empty() {
149        let cp = SimulationCheckpoint::empty("init");
150        assert_eq!(cp.body_count(), 0);
151        assert_eq!(cp.label, "init");
152        assert_eq!(cp.version, SimulationCheckpoint::FORMAT_VERSION);
153    }
154}