Move responsibility for extracting names from paths lower

This commit is contained in:
Lucien Greathouse
2021-08-24 17:59:53 -04:00
parent d484098781
commit 8954def25c
8 changed files with 86 additions and 68 deletions

View File

@@ -7,15 +7,16 @@ use serde::Serialize;
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
use super::meta_file::AdjacentMetadata; use super::{meta_file::AdjacentMetadata, util::PathExt};
pub fn snapshot_csv( pub fn snapshot_csv(
_context: &InstanceContext, _context: &InstanceContext,
vfs: &Vfs, vfs: &Vfs,
path: &Path, path: &Path,
instance_name: &str,
) -> anyhow::Result<Option<InstanceSnapshot>> { ) -> anyhow::Result<Option<InstanceSnapshot>> {
let meta_path = path.with_file_name(format!("{}.meta.json", instance_name)); let name = path.file_name_trim_end(".csv")?;
let meta_path = path.with_file_name(format!("{}.meta.json", name));
let contents = vfs.read(path)?; let contents = vfs.read(path)?;
let table_contents = convert_localization_csv(&contents).with_context(|| { let table_contents = convert_localization_csv(&contents).with_context(|| {
@@ -26,7 +27,7 @@ pub fn snapshot_csv(
})?; })?;
let mut snapshot = InstanceSnapshot::new() let mut snapshot = InstanceSnapshot::new()
.name(instance_name) .name(name)
.class_name("LocalizationTable") .class_name("LocalizationTable")
.properties(hashmap! { .properties(hashmap! {
"Contents".to_owned() => table_contents.into(), "Contents".to_owned() => table_contents.into(),
@@ -143,14 +144,10 @@ Ack,Ack!,,An exclamation of despair,¡Ay!"#,
let mut vfs = Vfs::new(imfs); let mut vfs = Vfs::new(imfs);
let instance_snapshot = snapshot_csv( let instance_snapshot =
&InstanceContext::default(), snapshot_csv(&InstanceContext::default(), &mut vfs, Path::new("/foo.csv"))
&mut vfs, .unwrap()
Path::new("/foo.csv"), .unwrap();
"foo",
)
.unwrap()
.unwrap();
insta::assert_yaml_snapshot!(instance_snapshot); insta::assert_yaml_snapshot!(instance_snapshot);
} }
@@ -175,14 +172,10 @@ Ack,Ack!,,An exclamation of despair,¡Ay!"#,
let mut vfs = Vfs::new(imfs); let mut vfs = Vfs::new(imfs);
let instance_snapshot = snapshot_csv( let instance_snapshot =
&InstanceContext::default(), snapshot_csv(&InstanceContext::default(), &mut vfs, Path::new("/foo.csv"))
&mut vfs, .unwrap()
Path::new("/foo.csv"), .unwrap();
"foo",
)
.unwrap()
.unwrap();
insta::assert_yaml_snapshot!(instance_snapshot); insta::assert_yaml_snapshot!(instance_snapshot);
} }

View File

@@ -9,14 +9,14 @@ use crate::{
snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}, snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot},
}; };
use super::meta_file::AdjacentMetadata; use super::{meta_file::AdjacentMetadata, util::PathExt};
pub fn snapshot_json( pub fn snapshot_json(
context: &InstanceContext, context: &InstanceContext,
vfs: &Vfs, vfs: &Vfs,
path: &Path, path: &Path,
instance_name: &str,
) -> anyhow::Result<Option<InstanceSnapshot>> { ) -> anyhow::Result<Option<InstanceSnapshot>> {
let name = path.file_name_trim_end(".json")?;
let contents = vfs.read(path)?; let contents = vfs.read(path)?;
let value: serde_json::Value = serde_json::from_slice(&contents) let value: serde_json::Value = serde_json::from_slice(&contents)
@@ -28,10 +28,10 @@ pub fn snapshot_json(
"Source".to_owned() => as_lua.into(), "Source".to_owned() => as_lua.into(),
}; };
let meta_path = path.with_file_name(format!("{}.meta.json", instance_name)); let meta_path = path.with_file_name(format!("{}.meta.json", name));
let mut snapshot = InstanceSnapshot::new() let mut snapshot = InstanceSnapshot::new()
.name(instance_name) .name(name)
.class_name("ModuleScript") .class_name("ModuleScript")
.properties(properties) .properties(properties)
.metadata( .metadata(
@@ -107,7 +107,6 @@ mod test {
&InstanceContext::default(), &InstanceContext::default(),
&mut vfs, &mut vfs,
Path::new("/foo.json"), Path::new("/foo.json"),
"foo",
) )
.unwrap() .unwrap()
.unwrap(); .unwrap();

View File

@@ -9,12 +9,15 @@ use crate::{
snapshot::{InstanceContext, InstanceSnapshot}, snapshot::{InstanceContext, InstanceSnapshot},
}; };
use super::util::PathExt;
pub fn snapshot_json_model( pub fn snapshot_json_model(
context: &InstanceContext, context: &InstanceContext,
vfs: &Vfs, vfs: &Vfs,
path: &Path, path: &Path,
instance_name: &str,
) -> anyhow::Result<Option<InstanceSnapshot>> { ) -> anyhow::Result<Option<InstanceSnapshot>> {
let name = path.file_name_trim_end(".model.json")?;
let contents = vfs.read(path)?; let contents = vfs.read(path)?;
let contents_str = str::from_utf8(&contents) let contents_str = str::from_utf8(&contents)
.with_context(|| format!("File was not valid UTF-8: {}", path.display()))?; .with_context(|| format!("File was not valid UTF-8: {}", path.display()))?;
@@ -28,7 +31,7 @@ pub fn snapshot_json_model(
let mut snapshot = instance let mut snapshot = instance
.core .core
.into_snapshot(instance_name.to_owned()) .into_snapshot(name.to_owned())
.with_context(|| format!("Could not load JSON model: {}", path.display()))?; .with_context(|| format!("Could not load JSON model: {}", path.display()))?;
snapshot.metadata = snapshot snapshot.metadata = snapshot
@@ -133,7 +136,6 @@ mod test {
&InstanceContext::default(), &InstanceContext::default(),
&mut vfs, &mut vfs,
Path::new("/foo.model.json"), Path::new("/foo.model.json"),
"foo",
) )
.unwrap() .unwrap()
.unwrap(); .unwrap();

View File

@@ -33,7 +33,7 @@ use self::{
rbxm::snapshot_rbxm, rbxm::snapshot_rbxm,
rbxmx::snapshot_rbxmx, rbxmx::snapshot_rbxmx,
txt::snapshot_txt, txt::snapshot_txt,
util::match_file_name, util::PathExt,
}; };
pub use self::project::snapshot_project_node; pub use self::project::snapshot_project_node;
@@ -73,7 +73,7 @@ pub fn snapshot_from_vfs(
snapshot_dir(context, vfs, path) snapshot_dir(context, vfs, path)
} else { } else {
if let Some(name) = match_file_name(path, ".lua") { if let Ok(name) = path.file_name_trim_end(".lua") {
match name { match name {
// init scripts are handled elsewhere and should not turn into // init scripts are handled elsewhere and should not turn into
// their own children. // their own children.
@@ -81,23 +81,23 @@ pub fn snapshot_from_vfs(
_ => return snapshot_lua(context, vfs, path), _ => return snapshot_lua(context, vfs, path),
} }
} else if let Some(_name) = match_file_name(path, ".project.json") { } else if path.file_name_ends_with(".project.json") {
return snapshot_project(context, vfs, path); return snapshot_project(context, vfs, path);
} else if let Some(name) = match_file_name(path, ".model.json") { } else if path.file_name_ends_with(".model.json") {
return snapshot_json_model(context, vfs, path, name); return snapshot_json_model(context, vfs, path);
} else if let Some(_name) = match_file_name(path, ".meta.json") { } else if path.file_name_ends_with(".meta.json") {
// .meta.json files do not turn into their own instances. // .meta.json files do not turn into their own instances.
return Ok(None); return Ok(None);
} else if let Some(name) = match_file_name(path, ".json") { } else if path.file_name_ends_with(".json") {
return snapshot_json(context, vfs, path, name); return snapshot_json(context, vfs, path);
} else if let Some(name) = match_file_name(path, ".csv") { } else if path.file_name_ends_with(".csv") {
return snapshot_csv(context, vfs, path, name); return snapshot_csv(context, vfs, path);
} else if let Some(name) = match_file_name(path, ".txt") { } else if path.file_name_ends_with(".txt") {
return snapshot_txt(context, vfs, path, name); return snapshot_txt(context, vfs, path);
} else if let Some(name) = match_file_name(path, ".rbxmx") { } else if path.file_name_ends_with(".rbxmx") {
return snapshot_rbxmx(context, vfs, path, name); return snapshot_rbxmx(context, vfs, path);
} else if let Some(name) = match_file_name(path, ".rbxm") { } else if path.file_name_ends_with(".rbxm") {
return snapshot_rbxm(context, vfs, path, name); return snapshot_rbxm(context, vfs, path);
} }
Ok(None) Ok(None)

View File

@@ -5,12 +5,15 @@ use memofs::Vfs;
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
use super::util::PathExt;
pub fn snapshot_rbxm( pub fn snapshot_rbxm(
context: &InstanceContext, context: &InstanceContext,
vfs: &Vfs, vfs: &Vfs,
path: &Path, path: &Path,
instance_name: &str,
) -> anyhow::Result<Option<InstanceSnapshot>> { ) -> anyhow::Result<Option<InstanceSnapshot>> {
let name = path.file_name_trim_end(".rbxm")?;
let temp_tree = rbx_binary::from_reader(vfs.read(path)?.as_slice()) let temp_tree = rbx_binary::from_reader(vfs.read(path)?.as_slice())
.with_context(|| format!("Malformed rbxm file: {}", path.display()))?; .with_context(|| format!("Malformed rbxm file: {}", path.display()))?;
@@ -19,7 +22,7 @@ pub fn snapshot_rbxm(
if children.len() == 1 { if children.len() == 1 {
let snapshot = InstanceSnapshot::from_tree(&temp_tree, children[0]) let snapshot = InstanceSnapshot::from_tree(&temp_tree, children[0])
.name(instance_name) .name(name)
.metadata( .metadata(
InstanceMetadata::new() InstanceMetadata::new()
.instigating_source(path) .instigating_source(path)
@@ -58,7 +61,6 @@ mod test {
&InstanceContext::default(), &InstanceContext::default(),
&mut vfs, &mut vfs,
Path::new("/foo.rbxm"), Path::new("/foo.rbxm"),
"foo",
) )
.unwrap() .unwrap()
.unwrap(); .unwrap();

View File

@@ -5,12 +5,15 @@ use memofs::Vfs;
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
use super::util::PathExt;
pub fn snapshot_rbxmx( pub fn snapshot_rbxmx(
context: &InstanceContext, context: &InstanceContext,
vfs: &Vfs, vfs: &Vfs,
path: &Path, path: &Path,
instance_name: &str,
) -> anyhow::Result<Option<InstanceSnapshot>> { ) -> anyhow::Result<Option<InstanceSnapshot>> {
let name = path.file_name_trim_end(".rbxmx")?;
let options = rbx_xml::DecodeOptions::new() let options = rbx_xml::DecodeOptions::new()
.property_behavior(rbx_xml::DecodePropertyBehavior::ReadUnknown); .property_behavior(rbx_xml::DecodePropertyBehavior::ReadUnknown);
@@ -22,7 +25,7 @@ pub fn snapshot_rbxmx(
if children.len() == 1 { if children.len() == 1 {
let snapshot = InstanceSnapshot::from_tree(&temp_tree, children[0]) let snapshot = InstanceSnapshot::from_tree(&temp_tree, children[0])
.name(instance_name) .name(name)
.metadata( .metadata(
InstanceMetadata::new() InstanceMetadata::new()
.instigating_source(path) .instigating_source(path)
@@ -71,7 +74,6 @@ mod test {
&InstanceContext::default(), &InstanceContext::default(),
&mut vfs, &mut vfs,
Path::new("/foo.rbxmx"), Path::new("/foo.rbxmx"),
"foo",
) )
.unwrap() .unwrap()
.unwrap(); .unwrap();

View File

@@ -6,14 +6,15 @@ use memofs::{IoResultExt, Vfs};
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
use super::meta_file::AdjacentMetadata; use super::{meta_file::AdjacentMetadata, util::PathExt};
pub fn snapshot_txt( pub fn snapshot_txt(
context: &InstanceContext, context: &InstanceContext,
vfs: &Vfs, vfs: &Vfs,
path: &Path, path: &Path,
instance_name: &str,
) -> anyhow::Result<Option<InstanceSnapshot>> { ) -> anyhow::Result<Option<InstanceSnapshot>> {
let name = path.file_name_trim_end(".txt")?;
let contents = vfs.read(path)?; let contents = vfs.read(path)?;
let contents_str = str::from_utf8(&contents) let contents_str = str::from_utf8(&contents)
.with_context(|| format!("File was not valid UTF-8: {}", path.display()))? .with_context(|| format!("File was not valid UTF-8: {}", path.display()))?
@@ -23,10 +24,10 @@ pub fn snapshot_txt(
"Value".to_owned() => contents_str.into(), "Value".to_owned() => contents_str.into(),
}; };
let meta_path = path.with_file_name(format!("{}.meta.json", instance_name)); let meta_path = path.with_file_name(format!("{}.meta.json", name));
let mut snapshot = InstanceSnapshot::new() let mut snapshot = InstanceSnapshot::new()
.name(instance_name) .name(name)
.class_name("StringValue") .class_name("StringValue")
.properties(properties) .properties(properties)
.metadata( .metadata(
@@ -58,14 +59,10 @@ mod test {
let mut vfs = Vfs::new(imfs.clone()); let mut vfs = Vfs::new(imfs.clone());
let instance_snapshot = snapshot_txt( let instance_snapshot =
&InstanceContext::default(), snapshot_txt(&InstanceContext::default(), &mut vfs, Path::new("/foo.txt"))
&mut vfs, .unwrap()
Path::new("/foo.txt"), .unwrap();
"foo",
)
.unwrap()
.unwrap();
insta::assert_yaml_snapshot!(instance_snapshot); insta::assert_yaml_snapshot!(instance_snapshot);
} }

View File

@@ -1,5 +1,7 @@
use std::path::Path; use std::path::Path;
use anyhow::Context;
/// If the given string ends up with the given suffix, returns the portion of /// If the given string ends up with the given suffix, returns the portion of
/// the string before the suffix. /// the string before the suffix.
pub fn match_trailing<'a>(input: &'a str, suffix: &str) -> Option<&'a str> { pub fn match_trailing<'a>(input: &'a str, suffix: &str) -> Option<&'a str> {
@@ -11,10 +13,31 @@ pub fn match_trailing<'a>(input: &'a str, suffix: &str) -> Option<&'a str> {
} }
} }
/// If the given path has a file name, and that file name ends with the given pub trait PathExt {
/// suffix, returns the portion of the file name before the given suffix. fn file_name_ends_with(&self, suffix: &str) -> bool;
pub fn match_file_name<'a>(path: &'a Path, suffix: &str) -> Option<&'a str> { fn file_name_trim_end<'a>(&'a self, suffix: &str) -> anyhow::Result<&'a str>;
let file_name = path.file_name()?.to_str()?; }
match_trailing(&file_name, suffix) impl<P> PathExt for P
where
P: AsRef<Path>,
{
fn file_name_ends_with(&self, suffix: &str) -> bool {
self.as_ref()
.file_name()
.and_then(|name| name.to_str())
.map(|name| name.ends_with(suffix))
.unwrap_or(false)
}
fn file_name_trim_end<'a>(&'a self, suffix: &str) -> anyhow::Result<&'a str> {
let path = self.as_ref();
let file_name = path
.file_name()
.and_then(|name| name.to_str())
.with_context(|| format!("Path did not have a file name: {}", path.display()))?;
match_trailing(&file_name, suffix)
.with_context(|| format!("Path did not end in {}: {}", suffix, path.display()))
}
} }