1use crate::{
4 cells::{Coord, State},
5 config::Config,
6 error::Error,
7 poly_world::PolyWorld,
8 rules::Rule,
9 search::{Algorithm, SetCell},
10 world::World,
11};
12use serde::{Deserialize, Serialize};
13use std::time::Duration;
14
15use std::collections::BTreeMap;
16
17#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
19pub enum ReasonSer {
20 Known,
22
23 Decide,
25
26 Rule(Coord),
28
29 Sym(Coord),
31
32 Deduce,
34
35 Clause(Vec<Coord>),
37
38 TryAnother(usize),
45}
46
47#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
49pub struct SetCellSer {
50 pub(crate) coord: Coord,
52
53 pub(crate) state: State,
55
56 pub(crate) reason: ReasonSer,
58}
59
60#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
62#[serde(default)]
63pub struct WorldSer {
64 pub config: Config,
66
67 pub conflicts: u64,
69
70 pub set_stack: Vec<SetCellSer>,
74
75 pub check_index: u32,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub timing: Option<Duration>,
85
86 #[serde(skip_serializing_if = "BTreeMap::is_empty")]
88 pub extra: BTreeMap<String, String>,
89}
90
91impl WorldSer {
92 pub fn deser<R: Rule, A: Algorithm<R>>(&self, world: &mut World<R, A>) -> Result<(), Error> {
94 for &SetCellSer {
95 coord,
96 state,
97 ref reason,
98 } in &self.set_stack
99 {
100 let cell = world.find_cell(coord).ok_or(Error::SetCellError(coord))?;
101 if let Some(old_state) = cell.state.get() {
102 if old_state != state {
103 return Err(Error::SetCellError(coord));
104 }
105 } else if state.0 >= world.rule.gen() {
106 return Err(Error::InvalidState(coord, state));
107 } else {
108 let reason = A::deser_reason(world, reason)?;
109 let cell = cell;
110 world.set_cell(cell, state, reason).ok();
111 }
112 }
113 world.conflicts = self.conflicts;
114 if self.check_index < self.set_stack.len() as u32 {
115 world.check_index = self.check_index;
116 }
117 Ok(())
118 }
119
120 pub fn world(&self) -> Result<PolyWorld, Error> {
122 let mut world = self.config.world()?;
123 world.deser(self)?;
124 Ok(world)
125 }
126}
127
128impl<R: Rule, A: Algorithm<R>> World<R, A> {
129 #[inline]
131 pub fn ser(&self) -> WorldSer {
132 WorldSer {
133 config: self.config.clone(),
134 conflicts: self.conflicts,
135 set_stack: self.set_stack.iter().map(SetCell::ser).collect(),
136 check_index: self.check_index,
137 timing: None,
138 extra: BTreeMap::new(),
139 }
140 }
141
142 #[inline]
144 pub fn deser(&mut self, ser: &WorldSer) -> Result<(), Error> {
145 ser.deser(self)
146 }
147}