|
@@ -1,52 +1,94 @@
|
|
// Read a Ksudoku's XML save file.
|
|
// Read a Ksudoku's XML save file.
|
|
-
|
|
|
|
-use serde_derive::{Deserialize, Serialize};
|
|
|
|
-use serde_xml_rs::from_reader; // , from_str, to_string};
|
|
|
|
-use serde_xml_rs::to_writer;
|
|
|
|
|
|
+use std::fs::File;
|
|
|
|
+use std::io::BufReader;
|
|
|
|
+use xml::reader::{EventReader, XmlEvent};
|
|
|
|
+use xml::writer::XmlEvent as WrXmlEvent;
|
|
|
|
+use xml::EmitterConfig;
|
|
|
|
|
|
use std::error::Error;
|
|
use std::error::Error;
|
|
-use std::fs::File;
|
|
|
|
|
|
|
|
-#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
|
|
|
-struct Graph {
|
|
|
|
- order: i32,
|
|
|
|
- #[serde(rename = "type")]
|
|
|
|
- game_type: String,
|
|
|
|
- #[serde(rename = "specific-type")]
|
|
|
|
- specific_type: String,
|
|
|
|
-}
|
|
|
|
|
|
+pub fn load_ksudoku(filename: std::path::PathBuf) -> Result<String, Box<dyn Error>> {
|
|
|
|
+ let fh = File::open(filename)?;
|
|
|
|
+ let buffer = BufReader::new(fh);
|
|
|
|
+ let parser = EventReader::new(buffer);
|
|
|
|
+ // I'm interested in values and (maybe) solution
|
|
|
|
+ let mut values: String = String::from("");
|
|
|
|
+ let mut element_name: String = String::from("");
|
|
|
|
|
|
-#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
|
|
|
-struct Puzzle {
|
|
|
|
- graph: Graph,
|
|
|
|
- values: String,
|
|
|
|
- solution: String,
|
|
|
|
-}
|
|
|
|
|
|
+ for e in parser {
|
|
|
|
+ match e {
|
|
|
|
+ Ok(XmlEvent::StartElement { name, .. }) => {
|
|
|
|
+ element_name = name.local_name.clone();
|
|
|
|
+ if element_name == "graph" {
|
|
|
|
+ // Check the attributes here
|
|
|
|
+ // <graph specific-type="Plain" type="sudoku" order="9"/>
|
|
|
|
+ // Verify these are correct / not some other puzzle type!
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Ok(XmlEvent::Characters(text)) => {
|
|
|
|
+ if element_name == "values" {
|
|
|
|
+ values = text.clone();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Err(e) => {
|
|
|
|
+ return Err(Box::new(e));
|
|
|
|
+ }
|
|
|
|
+ _ => {}
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
-#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
|
|
|
-struct Game {
|
|
|
|
- #[serde(rename = "had-help")]
|
|
|
|
- help: i16,
|
|
|
|
- #[serde(rename = "msecs-elapsed")]
|
|
|
|
- elapsed: u32,
|
|
|
|
- puzzle: Puzzle,
|
|
|
|
-}
|
|
|
|
-#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
|
|
|
-struct Ksudoku {
|
|
|
|
- game: Game,
|
|
|
|
|
|
+ Ok(values)
|
|
}
|
|
}
|
|
|
|
|
|
-pub fn load_ksudoku(filename: std::path::PathBuf) -> Result<String, Box<dyn Error>> {
|
|
|
|
- let fh = File::open(filename)?;
|
|
|
|
- let puzzle: Ksudoku = from_reader(fh)?;
|
|
|
|
- Ok(puzzle.game.puzzle.values.clone())
|
|
|
|
-}
|
|
|
|
|
|
+pub fn save_ksudoku(
|
|
|
|
+ filename: std::path::PathBuf,
|
|
|
|
+ puz: &String,
|
|
|
|
+ sol: &String,
|
|
|
|
+) -> Result<(), Box<dyn Error>> {
|
|
|
|
+ let fh = File::create(filename)?;
|
|
|
|
+ let mut writer = EmitterConfig::new().perform_indent(true).create_writer(fh);
|
|
|
|
+
|
|
|
|
+ let mut event: WrXmlEvent = WrXmlEvent::start_element("ksudoku").into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::start_element("game")
|
|
|
|
+ .attr("had-help", "0")
|
|
|
|
+ .attr("msecs-elapsed", "0")
|
|
|
|
+ .into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::start_element("puzzle").into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::start_element("graph").attr("specific-type", "Plain")
|
|
|
|
+ .attr("type", "sudoku").attr("order", "9").into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::end_element().into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+
|
|
|
|
+ // values (puzzle)
|
|
|
|
+ event = WrXmlEvent::start_element("values").into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::characters(puz).into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::end_element().into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+
|
|
|
|
+ // solution
|
|
|
|
+ event = WrXmlEvent::start_element("solution").into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::characters(sol).into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::end_element().into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
|
|
-pub fn save_ksudoku(filename: std::path::PathBuf, puz: &String, sol: &String) -> Result<(), Box<dyn Error>> {
|
|
|
|
|
|
+ event = WrXmlEvent::end_element().into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::end_element().into();
|
|
|
|
+ writer.write(event)?;
|
|
|
|
+ event = WrXmlEvent::end_element().into();
|
|
|
|
+ writer.write(event)?;
|
|
/*
|
|
/*
|
|
let pStr: String = puzzle.save_to_tld(start_ch: 'b', blank: '_');
|
|
let pStr: String = puzzle.save_to_tld(start_ch: 'b', blank: '_');
|
|
let solStr: solution.save_to_tld(start_ch: 'b', blank: '_');
|
|
let solStr: solution.save_to_tld(start_ch: 'b', blank: '_');
|
|
- */
|
|
|
|
|
|
+
|
|
let ksudoko = Ksudoku {
|
|
let ksudoko = Ksudoku {
|
|
game: Game {
|
|
game: Game {
|
|
help: 0,
|
|
help: 0,
|
|
@@ -64,6 +106,6 @@ pub fn save_ksudoku(filename: std::path::PathBuf, puz: &String, sol: &String) ->
|
|
};
|
|
};
|
|
let fh = File::create(filename)?;
|
|
let fh = File::create(filename)?;
|
|
let _res = to_writer(fh, &ksudoko)?;
|
|
let _res = to_writer(fh, &ksudoko)?;
|
|
-
|
|
|
|
|
|
+ */
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|