Skip to content

Commit 23ab6cb

Browse files
authored
Windows support (#24)
1 parent 7490ebe commit 23ab6cb

File tree

4 files changed

+36
-23
lines changed

4 files changed

+36
-23
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "docxtools"
3-
version = "0.9.1-SNAPSHOT"
3+
version = "0.10.0-SNAPSHOT"
44
edition = "2021"
55
authors = ["David Bosschaert <[email protected]>"]
66
license = "Apache-2.0"

src/file_util.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,37 @@
1-
use std::path::Path;
1+
use std::path::{MAIN_SEPARATOR, MAIN_SEPARATOR_STR, Path};
22

33
pub struct FileUtil {
44
}
55

66
impl FileUtil {
7+
pub fn normalize_path(s: &str) -> String {
8+
let src_char = if MAIN_SEPARATOR == '/' {
9+
"\\"
10+
} else {
11+
"/"
12+
};
13+
14+
s.replace(src_char, MAIN_SEPARATOR_STR)
15+
}
16+
717
pub fn get_sub_path(path: &Path, base_dir: &str) -> String {
18+
let nbase_dir = FileUtil::normalize_path(base_dir);
19+
820
let base;
9-
if base_dir.ends_with("/") {
10-
base = base_dir.to_owned();
21+
if nbase_dir.ends_with(MAIN_SEPARATOR_STR) {
22+
base = nbase_dir;
1123
} else {
12-
base = base_dir.to_owned() + "/";
24+
base = nbase_dir + MAIN_SEPARATOR_STR;
1325
}
1426

1527
let sub_path;
1628

1729
let full_path = path.to_string_lossy();
18-
if full_path.starts_with(&base) {
19-
sub_path = &full_path[base.len()..];
30+
let nfull_path = FileUtil::normalize_path(&full_path);
31+
if nfull_path.starts_with(&base) {
32+
sub_path = &nfull_path[base.len()..];
2033
} else {
21-
sub_path = &full_path;
34+
sub_path = &nfull_path;
2235
}
2336

2437
sub_path.to_owned()
@@ -34,20 +47,20 @@ mod tests {
3447
fn test_get_sub_path() {
3548
let p = Path::new("/some/where/on/the/rainbow.docx");
3649
let b = "/some/where/on/";
37-
assert_eq!("the/rainbow.docx", FileUtil::get_sub_path(p, b));
50+
assert_eq!(FileUtil::normalize_path("the/rainbow.docx"), FileUtil::get_sub_path(p, b));
3851
}
3952

4053
#[test]
4154
fn test_get_sub_path1() {
4255
let p = Path::new("/some/where/on/the/rainbow.docx");
4356
let b = "/some/where/on";
44-
assert_eq!("the/rainbow.docx", FileUtil::get_sub_path(p, b));
57+
assert_eq!(FileUtil::normalize_path("the/rainbow.docx"), FileUtil::get_sub_path(p, b));
4558
}
4659

4760
#[test]
4861
fn test_get_sub_path2() {
4962
let b = "/some/where/on/";
5063
let p = Path::new("/elsewhere/cloud.docx");
51-
assert_eq!("/elsewhere/cloud.docx", FileUtil::get_sub_path(p, b));
64+
assert_eq!(FileUtil::normalize_path("/elsewhere/cloud.docx"), FileUtil::get_sub_path(p, b));
5265
}
5366
}

src/xml_util.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use regex::Regex;
77
use std::collections::{BTreeMap, HashMap};
88
use std::fs::{File, self};
99
use std::io::{BufReader, BufWriter};
10-
use std::path::{Path, PathBuf};
10+
use std::path::{Path, PathBuf, MAIN_SEPARATOR, MAIN_SEPARATOR_STR};
1111
use std::str;
1212
use uuid::Uuid;
1313
use unicase::UniCase;
@@ -154,15 +154,15 @@ impl XMLUtil {
154154

155155
let mut rels_files = vec!();
156156
for f in files {
157-
let last_slash = f.rfind('/').expect(&f);
157+
let last_slash = f.rfind(MAIN_SEPARATOR).expect(&f);
158158
let mut new_fn = String::new();
159159
new_fn.push_str(&f[..last_slash]);
160160
new_fn.push_str("/_");
161161
new_fn.push_str(rels_extension);
162162
new_fn.push_str(&f[last_slash..]);
163163
new_fn.push('.');
164164
new_fn.push_str(rels_extension);
165-
rels_files.push(new_fn);
165+
rels_files.push(FileUtil::normalize_path(&new_fn));
166166
}
167167

168168
rels_files
@@ -175,9 +175,9 @@ impl XMLUtil {
175175
/// `pattern` and `replacement` are used to search/replace operations.
176176
/// `output_file` optionally specifies a different output file for replacement operations.
177177
fn snr_xml(mode: Mode, dir: &str, src_file: &str, files: Option<Vec<String>>, output_file: Option<&str>) {
178-
let mut base_dir = dir.to_owned();
179-
if !dir.ends_with("/") {
180-
base_dir.push('/');
178+
let mut base_dir = FileUtil::normalize_path(dir);
179+
if !base_dir.ends_with(MAIN_SEPARATOR_STR) {
180+
base_dir.push(MAIN_SEPARATOR);
181181
}
182182

183183
for entry in WalkDir::new(dir).into_iter()
@@ -838,7 +838,7 @@ impl XMLUtil {
838838
} else {
839839
rel_pn = pn;
840840
}
841-
mappings.insert(rel_pn.to_string(),
841+
mappings.insert(FileUtil::normalize_path(rel_pn),
842842
str::from_utf8(cv.value.as_ref()).unwrap().to_string());
843843
}
844844
}

src/zip_util.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl ZipUtil {
151151
mod tests {
152152
use crate::file_util::FileUtil;
153153
use super::ZipUtil;
154-
use std::{path::Path, fs, io};
154+
use std::{path::MAIN_SEPARATOR_STR, path::Path, fs, io};
155155
use walkdir::WalkDir;
156156
use testdir::testdir;
157157

@@ -165,13 +165,13 @@ mod tests {
165165
let wd = WalkDir::new(&outdir);
166166
let extracts: Vec<String> = wd.into_iter()
167167
.map(|e| FileUtil::get_sub_path(&e.unwrap().path(), &outdir.to_string_lossy()))
168-
.filter(|e| !e.starts_with("/"))
168+
.filter(|e| !e.starts_with(MAIN_SEPARATOR_STR))
169169
.filter(|e| e.contains('.'))
170170
.collect();
171171

172172
assert!(extracts.contains(&"foo.test.txt".into()));
173173
assert!(extracts.contains(&"empty.file".into()));
174-
assert!(extracts.contains(&"sub/sub/[Content_Types].xml".into()));
174+
assert!(extracts.contains(&FileUtil::normalize_path("sub/sub/[Content_Types].xml")));
175175
assert_eq!(3, extracts.len(), "Should be only 3 files");
176176

177177
let empty_file = Path::new(&outdir).join("empty.file");
@@ -209,14 +209,14 @@ mod tests {
209209

210210
let extracts: Vec<String> = WalkDir::new(&expldir).into_iter()
211211
.map(|e| FileUtil::get_sub_path(&e.unwrap().path(), &expldir.to_string_lossy()))
212-
.filter(|e| !e.starts_with("/"))
212+
.filter(|e| !e.starts_with(MAIN_SEPARATOR_STR))
213213
.filter(|e| e.contains('.'))
214214
.collect();
215215

216216
assert_eq!(3, extracts.len());
217217
assert!(extracts.contains(&"foo.test.txt".into()));
218218
assert!(extracts.contains(&"empty.file".into()));
219-
assert!(extracts.contains(&"sub/sub/[Content_Types].xml".into()));
219+
assert!(extracts.contains(&FileUtil::normalize_path("sub/sub/[Content_Types].xml")));
220220

221221
let empty_file = Path::new(&expldir).join("empty.file");
222222
assert!(empty_file.is_file());

0 commit comments

Comments
 (0)