summaryrefslogtreecommitdiff
path: root/server/common/src/grit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/common/src/grit.rs')
-rw-r--r--server/common/src/grit.rs98
1 files changed, 78 insertions, 20 deletions
diff --git a/server/common/src/grit.rs b/server/common/src/grit.rs
index ee96500..9d01dac 100644
--- a/server/common/src/grit.rs
+++ b/server/common/src/grit.rs
@@ -4,7 +4,7 @@ use anyhow::Error;
use std::collections::VecDeque;
use std::fs;
use std::io::{BufReader, Read};
-use std::path::Path;
+use std::path::{Path, PathBuf};
use tokio::task::spawn_blocking;
use xml::attribute::OwnedAttribute;
use xml::reader::{EventReader, ParserConfig, XmlEvent};
@@ -1018,9 +1018,16 @@ fn parse_grit_part_element<R: Read>(
pub async fn parse_grit(path: impl AsRef<Path>) -> anyhow::Result<Grit> {
let path = path.as_ref().to_path_buf();
+ parse_grit_with_opener(move || Ok(BufReader::new(fs::File::open(path)?))).await
+}
+
+pub async fn parse_grit_with_opener<F, R>(opener: F) -> anyhow::Result<Grit>
+where
+ F: FnOnce() -> anyhow::Result<BufReader<R>> + Send + 'static,
+ R: Read,
+{
spawn_blocking(move || {
- let file = fs::File::open(path)?;
- let reader = BufReader::new(file);
+ let reader = opener()?;
let mut ereader = ParserConfig::new()
.ignore_comments(true)
.whitespace_to_characters(true)
@@ -1064,9 +1071,16 @@ pub async fn parse_grit(path: impl AsRef<Path>) -> anyhow::Result<Grit> {
pub async fn parse_grit_part(path: impl AsRef<Path>) -> anyhow::Result<GritPart> {
let path = path.as_ref().to_path_buf();
+ parse_grit_part_with_opener(|| Ok(BufReader::new(fs::File::open(path)?))).await
+}
+
+pub async fn parse_grit_part_with_opener<F, R>(opener: F) -> anyhow::Result<GritPart>
+where
+ F: FnOnce() -> anyhow::Result<BufReader<R>> + Send + 'static,
+ R: Read,
+{
spawn_blocking(move || {
- let file = fs::File::open(path)?;
- let reader = BufReader::new(file);
+ let reader = opener()?;
let mut ereader = ParserConfig::new()
.ignore_comments(true)
.whitespace_to_characters(true)
@@ -1121,20 +1135,20 @@ fn if_message_to_if_message_part(messages: Vec<IfMessage>) -> Vec<IfMessagePart>
.collect()
}
-async fn maybe_expand_message(message: &mut IfMessagePart, basepath: &Path) -> anyhow::Result<()> {
+async fn maybe_expand_message<F, R>(message: &mut IfMessagePart, opener: &F) -> anyhow::Result<()>
+where
+ F: Fn(&str) -> anyhow::Result<BufReader<R>> + Clone + Send + 'static,
+ R: Read,
+{
match message {
IfMessagePart::Message(_) => Ok(()),
IfMessagePart::Part {
file,
ref mut messages,
} => {
- let file_path = Path::new(file.as_str());
- let part_path = if let Some(parent) = basepath.parent() {
- parent.join(file_path)
- } else {
- file_path.to_path_buf()
- };
- let grit_part = parse_grit_part(part_path).await?;
+ let file = file.to_string();
+ let opener = opener.clone();
+ let grit_part = parse_grit_part_with_opener(move || opener(file.as_str())).await?;
*messages = if_message_to_if_message_part(grit_part.messages);
Ok(())
}
@@ -1142,23 +1156,60 @@ async fn maybe_expand_message(message: &mut IfMessagePart, basepath: &Path) -> a
expr: _,
ref mut message,
} => {
- Box::pin(expand_messages(message, basepath)).await?;
+ Box::pin(expand_messages(message, opener)).await?;
Ok(())
}
}
}
-async fn expand_messages(messages: &mut Vec<IfMessagePart>, basepath: &Path) -> anyhow::Result<()> {
+async fn expand_messages<F, R>(messages: &mut Vec<IfMessagePart>, opener: &F) -> anyhow::Result<()>
+where
+ F: Fn(&str) -> anyhow::Result<BufReader<R>> + Clone + Send + 'static,
+ R: Read,
+{
for message in messages {
- maybe_expand_message(message, basepath).await?;
+ maybe_expand_message(message, opener).await?;
}
Ok(())
}
pub async fn parse_grit_with_parts(path: impl AsRef<Path>) -> anyhow::Result<Grit> {
let path = path.as_ref();
- let mut grit = parse_grit(path).await?;
- expand_messages(&mut grit.release.messages.messages, path).await?;
+ if let Some(basepath) = path.parent() {
+ let basepath = basepath.to_path_buf();
+ parse_grit_with_parts_and_resolver(path, move |x| basepath.join(x)).await
+ } else {
+ parse_grit_with_parts_and_resolver(path, |x| PathBuf::from(x)).await
+ }
+}
+
+pub async fn parse_grit_with_parts_and_resolver<F>(
+ path: impl AsRef<Path>,
+ path_resolver: F,
+) -> anyhow::Result<Grit>
+where
+ F: Fn(&str) -> PathBuf + Send + Clone + 'static,
+{
+ let path = path.as_ref().to_path_buf();
+ let grit_opener = || Ok(BufReader::new(fs::File::open(path)?));
+ let part_opener = move |x: &str| {
+ let part_path = path_resolver(x);
+ Ok(BufReader::new(fs::File::open(part_path)?))
+ };
+ parse_grit_with_parts_and_opener(grit_opener, part_opener).await
+}
+
+pub async fn parse_grit_with_parts_and_opener<F, G, R>(
+ grit_opener: F,
+ part_opener: G,
+) -> anyhow::Result<Grit>
+where
+ F: FnOnce() -> anyhow::Result<BufReader<R>> + Send + 'static,
+ G: Fn(&str) -> anyhow::Result<BufReader<R>> + Clone + Send + 'static,
+ R: Read,
+{
+ let mut grit = parse_grit_with_opener(grit_opener).await?;
+ expand_messages(&mut grit.release.messages.messages, &part_opener).await?;
Ok(grit)
}
@@ -1513,9 +1564,16 @@ fn parse_xliff_element<R: Read>(
pub async fn parse_xlf(path: impl AsRef<Path>) -> anyhow::Result<TranslationFile> {
let path = path.as_ref().to_path_buf();
+ parse_xlf_with_opener(|| Ok(BufReader::new(fs::File::open(path)?))).await
+}
+
+pub async fn parse_xlf_with_opener<F, R>(opener: F) -> anyhow::Result<TranslationFile>
+where
+ F: FnOnce() -> anyhow::Result<BufReader<R>> + Send + 'static,
+ R: Read,
+{
spawn_blocking(move || {
- let file = fs::File::open(path)?;
- let reader = BufReader::new(file);
+ let reader = opener()?;
let mut ereader = ParserConfig::new()
.ignore_comments(true)
.whitespace_to_characters(true)