commit 9c7272ccc935f78d7b9aa0be5dcbe4ce717dae31
parent 4f6bc1c3897db4caff16f82512f46cbb7ec877e8
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Mon, 17 Jun 2024 14:55:14 -0700
Implement parse_manifest_file function
Diffstat:
6 files changed, 229 insertions(+), 1 deletion(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -5,3 +5,115 @@ version = 3
[[package]]
name = "coliru"
version = "0.0.0"
+dependencies = [
+ "serde",
+ "serde_yaml",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+
+[[package]]
+name = "indexmap"
+version = "2.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.85"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+
+[[package]]
+name = "serde"
+version = "1.0.203"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.203"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_yaml"
+version = "0.9.34+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
+dependencies = [
+ "indexmap",
+ "itoa",
+ "ryu",
+ "serde",
+ "unsafe-libyaml",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unsafe-libyaml"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
diff --git a/Cargo.toml b/Cargo.toml
@@ -4,3 +4,5 @@ version = "0.0.0"
edition = "2021"
[dependencies]
+serde = { version = "1.0", features = ["derive"] }
+serde_yaml = "0.9"
diff --git a/examples/1.yml b/examples/1.yml
@@ -0,0 +1,14 @@
+# Invalid manifest
+
+steps:
+ - not_copy:
+ - src: foo
+ dst: ~/foo
+ - src: bar
+ dst: ~/test/bar
+ tags: [ a, b ]
+
+ - copy:
+ - not_src: baz
+ dst: /baz
+ tags: [ b, c ]
diff --git a/examples/2.yml b/examples/2.yml
@@ -0,0 +1,14 @@
+# Valid manifest
+
+steps:
+ - copy:
+ - src: foo
+ dst: ~/foo
+ - src: bar
+ dst: ~/test/bar
+ tags: [ a, b ]
+
+ - copy:
+ - src: baz
+ dst: /baz
+ tags: [ b, c ]
diff --git a/src/main.rs b/src/main.rs
@@ -1,3 +1,5 @@
+mod manifest;
+mod tags;
+
fn main() {
- println!("Hello, world!");
}
diff --git a/src/manifest.rs b/src/manifest.rs
@@ -0,0 +1,84 @@
+use serde::{Serialize, Deserialize};
+use serde_yaml;
+use std::fs::read_to_string;
+use std::path::{Path, PathBuf};
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+pub struct CopyOptions {
+ src: PathBuf,
+ dst: PathBuf,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+pub struct Step {
+ copy: Vec<CopyOptions>,
+ tags: Vec<String>,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+pub struct Manifest {
+ steps: Vec<Step>,
+}
+
+/// Parse a coliru YAML manifest file
+pub fn parse_manifest_file(path: &Path) -> Result<Manifest, String> {
+ match read_to_string(path) {
+ Ok(raw) => match serde_yaml::from_str::<Manifest>(&raw) {
+ Ok(result) => Ok(result),
+ Err(why) => Err(why.to_string()),
+ }
+ Err(why) => Err(why.to_string()),
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[cfg(target_os = "linux")]
+ #[test]
+ fn parse_manifest_file_missing() {
+ let expected = "No such file or directory (os error 2)";
+ let actual = parse_manifest_file(Path::new("examples/0.yml"));
+ assert_eq!(actual, Err(String::from(expected)));
+ }
+
+ #[test]
+ fn parse_manifest_file_invalid() {
+ let expected = "steps[0]: missing field `copy` at line 4 column 5";
+ let actual = parse_manifest_file(Path::new("examples/1.yml"));
+ assert_eq!(actual, Err(String::from(expected)));
+ }
+
+ #[test]
+ fn parse_manifest_file_valid() {
+ let expected = Manifest {
+ steps: vec![
+ Step {
+ copy: vec![
+ CopyOptions{
+ src: PathBuf::from("foo"),
+ dst: PathBuf::from("~/foo")
+ },
+ CopyOptions{
+ src: PathBuf::from("bar"),
+ dst: PathBuf::from("~/test/bar")
+ },
+ ],
+ tags: vec![String::from("a"), String::from("b")],
+ },
+ Step {
+ copy: vec![
+ CopyOptions{
+ src: PathBuf::from("baz"),
+ dst: PathBuf::from("/baz")
+ },
+ ],
+ tags: vec![String::from("b"), String::from("c")],
+ }
+ ],
+ };
+ let actual = parse_manifest_file(Path::new("examples/2.yml"));
+ assert_eq!(actual, Ok(expected));
+ }
+}