Browse Source

Working save/load to ksudoku.

Steve Thielemann 6 months ago
parent
commit
730e6644f2
3 changed files with 82 additions and 42 deletions
  1. 1 3
      sudoku/Cargo.toml
  2. 80 38
      sudoku/src/ksudoku.rs
  3. 1 1
      sudoku/src/sudoku.rs

+ 1 - 3
sudoku/Cargo.toml

@@ -6,13 +6,11 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 
 [dependencies]
 [dependencies]
-serde = "1.0.196"
-serde-xml-rs = "0.6.0"
-serde_derive = "1.0.196"
 bit_field = "0.10.2"
 bit_field = "0.10.2"
 rand = "0.8.5"
 rand = "0.8.5"
 rand_chacha = "0.3.1"
 rand_chacha = "0.3.1"
 rand_core = { version = "0.6.4", features = ["getrandom"] }
 rand_core = { version = "0.6.4", features = ["getrandom"] }
+xml = "0.8.20"
 
 
 [lib]
 [lib]
 name = "sudoku"
 name = "sudoku"

+ 80 - 38
sudoku/src/ksudoku.rs

@@ -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(())
 }
 }

+ 1 - 1
sudoku/src/sudoku.rs

@@ -244,7 +244,7 @@ impl Sudoku {
             if self.board[pos(x, y) as usize] == 0 {
             if self.board[pos(x, y) as usize] == 0 {
                 result.push(blank);
                 result.push(blank);
             } else {
             } else {
-                result.push((start_ch as u8 + self.board[i as usize]) as char);
+                result.push((start_ch as u8 + self.board[pos(x,y) as usize]) as char);
             }
             }
             y += 1;
             y += 1;
             if y >= WIDTH {
             if y >= WIDTH {