Skip to content

Commit

Permalink
feat: add the ability to save pattern in the OXS format
Browse files Browse the repository at this point in the history
  • Loading branch information
niusia-ua committed Nov 2, 2024
1 parent b104655 commit 291aea1
Show file tree
Hide file tree
Showing 20 changed files with 966 additions and 329 deletions.
54 changes: 41 additions & 13 deletions src-tauri/src/commands/pattern.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use tauri::Manager;

use crate::{
error::CommandResult,
parser::{self, PatternFormat},
Expand All @@ -7,7 +9,7 @@ use crate::{

#[tauri::command]
pub fn load_pattern(file_path: std::path::PathBuf, state: tauri::State<AppStateType>) -> CommandResult<Vec<u8>> {
log::trace!("Loading pattern from {:?}", file_path);
log::trace!("Loading pattern");
let mut state = state.write().unwrap();
let pattern_key = PatternKey::from(file_path.clone());
let pattern = match state.patterns.get(&pattern_key) {
Expand All @@ -16,16 +18,20 @@ pub fn load_pattern(file_path: std::path::PathBuf, state: tauri::State<AppStateT
pattern.to_owned()
}
None => {
let pattern_format = PatternFormat::try_from(file_path.extension())?;
let pattern = match pattern_format {
let mut new_file_path = file_path.clone();
new_file_path.set_extension("oxs");

let mut pattern = match PatternFormat::try_from(file_path.extension())? {
PatternFormat::Xsd => parser::xsd::parse_pattern(file_path)?,
PatternFormat::Oxs => parser::oxs::parse_pattern(file_path)?,
PatternFormat::EmbProj => todo!(),
// PatternFormat::EmbProj => {
// let mut reader = std::fs::File::open(file_path)?;
// borsh::from_reader(&mut reader)?
// }
PatternFormat::EmbProj => todo!(),
};
pattern.file_path = new_file_path;

state.patterns.insert(pattern_key, pattern.clone());
pattern
}
Expand All @@ -35,34 +41,49 @@ pub fn load_pattern(file_path: std::path::PathBuf, state: tauri::State<AppStateT
}

#[tauri::command]
pub fn create_pattern(state: tauri::State<AppStateType>) -> (PatternKey, Vec<u8>) {
pub fn create_pattern<R: tauri::Runtime>(
app_handle: tauri::AppHandle<R>,
state: tauri::State<AppStateType>,
) -> CommandResult<(PatternKey, Vec<u8>)> {
log::trace!("Creating new pattern");
let mut state = state.write().unwrap();
let file_path = std::path::PathBuf::from(format!("Untitled-{:?}.json", std::time::Instant::now()));
let file_path = app_handle
.path()
.document_dir()?
.join(app_handle.config().product_name.clone().unwrap())
.join("Untitled.oxs");
let pattern_key = PatternKey::from(file_path.clone());
let pattern = PatternProject {
file_path: Some(file_path),
file_path,
pattern: Pattern::default(),
display_settings: DisplaySettings::new(2),
print_settings: PrintSettings::default(),
};
state.patterns.insert(pattern_key.clone(), pattern.clone());
log::trace!("Pattern has been created");
// It is safe to unwrap here, because the pattern is always serializable.
(pattern_key, borsh::to_vec(&pattern).unwrap())
Ok((pattern_key, borsh::to_vec(&pattern).unwrap()))
}

// TODO: Use a custom or different pattern format, but not the JSON.
#[tauri::command]
pub fn save_pattern(
pattern_key: PatternKey,
file_path: std::path::PathBuf,
state: tauri::State<AppStateType>,
) -> CommandResult<()> {
log::trace!("Saving pattern to {:?}", file_path);
let state = state.read().unwrap();
let pattern = state.patterns.get(&pattern_key).unwrap();
std::fs::write(file_path, borsh::to_vec(pattern)?)?;
log::trace!("Saving pattern");
let mut state = state.write().unwrap();
let patproj = state.patterns.get_mut(&pattern_key).unwrap();
patproj.file_path = file_path;
match PatternFormat::try_from(patproj.file_path.extension())? {
PatternFormat::Xsd => Err(anyhow::anyhow!("The XSD format is not supported for saving.")),
PatternFormat::Oxs => parser::oxs::save_pattern(patproj),
PatternFormat::EmbProj => todo!(),
// PatternFormat::EmbProj => {
// let mut reader = std::fs::File::open(file_path)?;
// borsh::from_reader(&mut reader)?
// }
}?;
log::trace!("Pattern saved");
Ok(())
}
Expand All @@ -73,3 +94,10 @@ pub fn close_pattern(pattern_key: PatternKey, state: tauri::State<AppStateType>)
state.write().unwrap().patterns.remove(&pattern_key);
log::trace!("Pattern closed");
}

#[tauri::command]
pub fn get_pattern_file_path(pattern_key: PatternKey, state: tauri::State<AppStateType>) -> String {
let state = state.read().unwrap();
let patproj = state.patterns.get(&pattern_key).unwrap();
patproj.file_path.to_string_lossy().to_string()
}
6 changes: 6 additions & 0 deletions src-tauri/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ impl From<std::io::Error> for CommandError {
}
}

impl From<tauri::Error> for CommandError {
fn from(error: tauri::Error) -> Self {
Self(anyhow::Error::from(error))
}
}

impl serde::Serialize for CommandError {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
serializer.serialize_str(&format!("{:#}", self.0))
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fn main() {
commands::pattern::create_pattern,
commands::pattern::save_pattern,
commands::pattern::close_pattern,
commands::pattern::get_pattern_file_path,
])
.run(tauri::generate_context!())
.expect("Error while running Embroidery Studio");
Expand Down
5 changes: 3 additions & 2 deletions src-tauri/src/parser/oxs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod utils;
mod v1_0;

mod parser;
pub use parser::parse_pattern;
#[allow(clippy::module_inception)]
mod oxs;
pub use oxs::*;
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::{
};

pub fn parse_pattern(file_path: std::path::PathBuf) -> Result<PatternProject> {
log::trace!("Parsing the OXS pattern");
log::info!("Parsing the OXS pattern");

let mut reader = quick_xml::Reader::from_file(&file_path)?;
let mut buf = Vec::new();
Expand Down Expand Up @@ -39,3 +39,8 @@ pub fn parse_pattern(file_path: std::path::PathBuf) -> Result<PatternProject> {

Ok(pattern_project)
}

pub fn save_pattern(patproj: &PatternProject) -> Result<()> {
log::info!("Saving the OXS pattern");
v1_0::save_pattern(patproj)
}
12 changes: 8 additions & 4 deletions src-tauri/src/parser/oxs/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,27 @@ impl FromStr for OxsVersion {
}
}

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Software {
Ursa,
UrsaSoftware,
EmbroideryStudio,
}

impl FromStr for Software {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Ursa Software" => Ok(Software::Ursa),
"Ursa Software" => Ok(Software::UrsaSoftware),
"Embroidery Studio" => Ok(Software::EmbroideryStudio),
_ => anyhow::bail!("Unsupported software: {s}"),
}
}
}

pub fn process_attributes(attributes: Attributes) -> Result<HashMap<String, String>> {
pub type MapAttributes = HashMap<String, String>;

pub fn process_attributes(attributes: Attributes) -> Result<MapAttributes> {
let mut map = HashMap::new();
for attr in attributes {
let attr = attr?;
Expand Down
Loading

0 comments on commit 291aea1

Please sign in to comment.