Basic manifest implementation
This commit is contained in:
		
							parent
							
								
									d9b23d4a24
								
							
						
					
					
						commit
						a00486eeaf
					
				
							
								
								
									
										169
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										169
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| 
						 | 
					@ -51,6 +51,18 @@ dependencies = [
 | 
				
			||||||
 "windows-sys",
 | 
					 "windows-sys",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "anyhow"
 | 
				
			||||||
 | 
					version = "1.0.91"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "cfg-if"
 | 
				
			||||||
 | 
					version = "1.0.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "clap"
 | 
					name = "clap"
 | 
				
			||||||
version = "4.5.20"
 | 
					version = "4.5.20"
 | 
				
			||||||
| 
						 | 
					@ -97,18 +109,72 @@ version = "1.0.2"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
 | 
					checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "form_urlencoded"
 | 
				
			||||||
 | 
					version = "1.2.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "percent-encoding",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "getrandom"
 | 
				
			||||||
 | 
					version = "0.2.15"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "wasi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "heck"
 | 
					name = "heck"
 | 
				
			||||||
version = "0.5.0"
 | 
					version = "0.5.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 | 
					checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "idna"
 | 
				
			||||||
 | 
					version = "0.5.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "unicode-bidi",
 | 
				
			||||||
 | 
					 "unicode-normalization",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "is_terminal_polyfill"
 | 
					name = "is_terminal_polyfill"
 | 
				
			||||||
version = "1.70.1"
 | 
					version = "1.70.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
 | 
					checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "itoa"
 | 
				
			||||||
 | 
					version = "1.0.11"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "libc"
 | 
				
			||||||
 | 
					version = "0.2.161"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "memchr"
 | 
				
			||||||
 | 
					version = "2.7.4"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "percent-encoding"
 | 
				
			||||||
 | 
					version = "2.3.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "proc-macro2"
 | 
					name = "proc-macro2"
 | 
				
			||||||
version = "1.0.89"
 | 
					version = "1.0.89"
 | 
				
			||||||
| 
						 | 
					@ -127,6 +193,44 @@ dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "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.214"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "serde_derive",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "serde_derive"
 | 
				
			||||||
 | 
					version = "1.0.214"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "syn",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "serde_json"
 | 
				
			||||||
 | 
					version = "1.0.132"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "itoa",
 | 
				
			||||||
 | 
					 "memchr",
 | 
				
			||||||
 | 
					 "ryu",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "strsim"
 | 
					name = "strsim"
 | 
				
			||||||
version = "0.11.1"
 | 
					version = "0.11.1"
 | 
				
			||||||
| 
						 | 
					@ -144,18 +248,76 @@ dependencies = [
 | 
				
			||||||
 "unicode-ident",
 | 
					 "unicode-ident",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "tinyvec"
 | 
				
			||||||
 | 
					version = "1.8.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "tinyvec_macros",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "tinyvec_macros"
 | 
				
			||||||
 | 
					version = "0.1.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "unicode-bidi"
 | 
				
			||||||
 | 
					version = "0.3.17"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "unicode-ident"
 | 
					name = "unicode-ident"
 | 
				
			||||||
version = "1.0.13"
 | 
					version = "1.0.13"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
 | 
					checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "unicode-normalization"
 | 
				
			||||||
 | 
					version = "0.1.24"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "tinyvec",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "url"
 | 
				
			||||||
 | 
					version = "2.5.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "form_urlencoded",
 | 
				
			||||||
 | 
					 "idna",
 | 
				
			||||||
 | 
					 "percent-encoding",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "utf8parse"
 | 
					name = "utf8parse"
 | 
				
			||||||
version = "0.2.2"
 | 
					version = "0.2.2"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 | 
					checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "uuid"
 | 
				
			||||||
 | 
					version = "1.11.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "getrandom",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "wasi"
 | 
				
			||||||
 | 
					version = "0.11.0+wasi-snapshot-preview1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows-sys"
 | 
					name = "windows-sys"
 | 
				
			||||||
version = "0.52.0"
 | 
					version = "0.52.0"
 | 
				
			||||||
| 
						 | 
					@ -254,3 +416,10 @@ version = "2.0.0"
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "xmpd-manifest"
 | 
					name = "xmpd-manifest"
 | 
				
			||||||
version = "2.0.0"
 | 
					version = "2.0.0"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "anyhow",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					 "serde_json",
 | 
				
			||||||
 | 
					 "url",
 | 
				
			||||||
 | 
					 "uuid",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,3 +18,8 @@ crate-type = ["rlib"]
 | 
				
			||||||
bench = false
 | 
					bench = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
 | 
					anyhow.workspace = true
 | 
				
			||||||
 | 
					uuid.workspace = true
 | 
				
			||||||
 | 
					serde.workspace = true
 | 
				
			||||||
 | 
					serde_json.workspace = true
 | 
				
			||||||
 | 
					url.workspace = true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,54 @@
 | 
				
			||||||
pub fn test() {
 | 
					use std::path::Path;
 | 
				
			||||||
    println!("Hello, world!");
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					pub mod tests;
 | 
				
			||||||
 | 
					pub mod store;
 | 
				
			||||||
 | 
					pub mod song;
 | 
				
			||||||
 | 
					pub mod playlist;
 | 
				
			||||||
 | 
					pub mod query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub type Result<T> = anyhow::Result<T>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct Manifest<ST: store::BaseStore> {
 | 
				
			||||||
 | 
					    store: Box<ST>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<ST: store::BaseStore + Clone> Manifest<ST> {
 | 
				
			||||||
 | 
					    pub fn new(p: &Path) -> Result<Self>{
 | 
				
			||||||
 | 
					        let mut store = ST::empty();
 | 
				
			||||||
 | 
					        if p.exists() {
 | 
				
			||||||
 | 
					            store.load_from(p)?;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            store.save_to(p)?; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        store.save_original_path(p);
 | 
				
			||||||
 | 
					        Ok(Self { 
 | 
				
			||||||
 | 
					            store: Box::new(store)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn store(&self) -> &ST {
 | 
				
			||||||
 | 
					        self.store.as_ref()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn store_mut(&mut self) -> &mut ST {
 | 
				
			||||||
 | 
					        self.store.as_mut()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn save(&self) -> Result<()> {
 | 
				
			||||||
 | 
					        self.store().save_to(self.store().get_original_path())?;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn load(&mut self) -> Result<()> {
 | 
				
			||||||
 | 
					        let p = self.store().get_original_path().to_path_buf();
 | 
				
			||||||
 | 
					        self.store_mut().load_from(&p)?;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								xmpd-manifest/src/playlist.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								xmpd-manifest/src/playlist.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, PartialOrd, Default)]
 | 
				
			||||||
 | 
					pub struct Playlist {
 | 
				
			||||||
 | 
					    name: String,
 | 
				
			||||||
 | 
					    author: String,
 | 
				
			||||||
 | 
					    songs: Vec<Uuid>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Playlist {
 | 
				
			||||||
 | 
					    pub fn name(&self) -> &str {
 | 
				
			||||||
 | 
					        &self.name
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn author(&self) -> &str {
 | 
				
			||||||
 | 
					        &self.author
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn songs(&self) -> &Vec<Uuid> {
 | 
				
			||||||
 | 
					        &self.songs
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn songs_mut(&mut self) -> &mut Vec<Uuid> {
 | 
				
			||||||
 | 
					        &mut self.songs
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_name(&mut self, v: &str) {
 | 
				
			||||||
 | 
					        self.name = v.to_string();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_author(&mut self, v: &str) {
 | 
				
			||||||
 | 
					        self.author = v.to_string();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn add_song(&mut self, v: &Uuid) {
 | 
				
			||||||
 | 
					        self.songs.push(v.clone());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn remove_song(&mut self, v: &Uuid) {
 | 
				
			||||||
 | 
					        for (i, id) in self.songs.iter().enumerate() {
 | 
				
			||||||
 | 
					            if id == v {
 | 
				
			||||||
 | 
					                self.songs.remove(i);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								xmpd-manifest/src/query/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								xmpd-manifest/src/query/mod.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					use std::marker::PhantomData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod playlist;
 | 
				
			||||||
 | 
					mod song;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct Query<QT: ?Sized> {
 | 
				
			||||||
 | 
					    playlist: Option<Uuid>,
 | 
				
			||||||
 | 
					    song: Option<Uuid>,
 | 
				
			||||||
 | 
					    _phantom: PhantomData<QT>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Query<()> {
 | 
				
			||||||
 | 
					    pub fn song(id: Uuid) -> Query<song::QuerySong> {
 | 
				
			||||||
 | 
					        Query {
 | 
				
			||||||
 | 
					            song: Some(id),
 | 
				
			||||||
 | 
					            playlist: None,
 | 
				
			||||||
 | 
					            _phantom: PhantomData
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn playlist(id: Uuid) -> Query<playlist::QueryPlaylist> {
 | 
				
			||||||
 | 
					        Query {
 | 
				
			||||||
 | 
					            playlist: Some(id),
 | 
				
			||||||
 | 
					            song: None,
 | 
				
			||||||
 | 
					            _phantom: PhantomData
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub trait QueryType {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										47
									
								
								xmpd-manifest/src/query/playlist.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								xmpd-manifest/src/query/playlist.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::{song::Song, store, Manifest};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::{Query, QueryType};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct QueryPlaylist;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl QueryType for QueryPlaylist {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Query<QueryPlaylist> {
 | 
				
			||||||
 | 
					    pub fn id(&self) -> &Uuid {
 | 
				
			||||||
 | 
					        if let Some(id) = &self.playlist {
 | 
				
			||||||
 | 
					            return id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        unreachable!()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn name<'a, ST: store::BaseStore + Clone>(&self, manifest: &'a Manifest<ST>) -> Option<&'a str> {
 | 
				
			||||||
 | 
					        let pl = manifest.store().get_playlist(self.id())?;
 | 
				
			||||||
 | 
					        Some(pl.name())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_name<ST: store::BaseStore + Clone>(&self, manifest: &mut Manifest<ST>, name: &str) -> Option<()> {
 | 
				
			||||||
 | 
					        let pl = manifest.store_mut().get_playlist_mut(self.id())?;
 | 
				
			||||||
 | 
					        pl.set_name(name);
 | 
				
			||||||
 | 
					        Some(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn author<'a, ST: store::BaseStore + Clone>(&self, manifest: &'a Manifest<ST>) -> Option<&'a str> {
 | 
				
			||||||
 | 
					        let pl = manifest.store().get_playlist(self.id())?;
 | 
				
			||||||
 | 
					        Some(pl.author())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_author<ST: store::BaseStore + Clone>(&self, manifest: &mut Manifest<ST>, author: &str) -> Option<()> {
 | 
				
			||||||
 | 
					        let pl = manifest.store_mut().get_playlist_mut(self.id())?;
 | 
				
			||||||
 | 
					        pl.set_author(author);
 | 
				
			||||||
 | 
					        Some(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn songs<'a, ST: store::BaseStore + Clone>(&self, manifest: &'a Manifest<ST>) -> Option<&'a Vec<Uuid>> {
 | 
				
			||||||
 | 
					        let pl = manifest.store().get_playlist(self.id())?;
 | 
				
			||||||
 | 
					        Some(pl.songs())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn add_song<ST: store::BaseStore + Clone>(&self, manifest: &mut Manifest<ST>, song: Song) -> Option<Uuid> {
 | 
				
			||||||
 | 
					        let pl = manifest.store_mut().get_playlist_mut(self.id())?;
 | 
				
			||||||
 | 
					        let id = Uuid::new_v4();
 | 
				
			||||||
 | 
					        pl.add_song(&id);
 | 
				
			||||||
 | 
					        manifest.store_mut().get_songs_mut().insert(id, song);
 | 
				
			||||||
 | 
					        Some(id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										68
									
								
								xmpd-manifest/src/query/song.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								xmpd-manifest/src/query/song.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					use std::str::FromStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use url::Url;
 | 
				
			||||||
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::{song::SourceType, store, Manifest};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::{Query, QueryType};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct QuerySong;
 | 
				
			||||||
 | 
					impl QueryType for QuerySong {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Query<QuerySong> {
 | 
				
			||||||
 | 
					    pub fn id(&self) -> &Uuid {
 | 
				
			||||||
 | 
					        if let Some(id) = &self.song {
 | 
				
			||||||
 | 
					            return id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        unreachable!()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn name<'a, ST: store::BaseStore + Clone>(&self, manifest: &'a Manifest<ST>) -> Option<&'a str> {
 | 
				
			||||||
 | 
					        let pl = manifest.store().get_song(self.id())?;
 | 
				
			||||||
 | 
					        Some(pl.name())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_name<ST: store::BaseStore + Clone>(&self, manifest: &mut Manifest<ST>, name: &str) -> Option<()> {
 | 
				
			||||||
 | 
					        let pl = manifest.store_mut().get_song_mut(self.id())?;
 | 
				
			||||||
 | 
					        pl.set_name(name);
 | 
				
			||||||
 | 
					        Some(())
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					    pub fn author<'a, ST: store::BaseStore + Clone>(&self, manifest: &'a Manifest<ST>) -> Option<&'a str> {
 | 
				
			||||||
 | 
					        let pl = manifest.store().get_song(self.id())?;
 | 
				
			||||||
 | 
					        Some(pl.author())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_author<ST: store::BaseStore + Clone>(&self, manifest: &mut Manifest<ST>, author: &str) -> Option<()> {
 | 
				
			||||||
 | 
					        let pl = manifest.store_mut().get_song_mut(self.id())?;
 | 
				
			||||||
 | 
					        pl.set_author(author);
 | 
				
			||||||
 | 
					        Some(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn url<'a, ST: store::BaseStore + Clone>(&self, manifest: &'a Manifest<ST>) -> Option<&'a Url> {
 | 
				
			||||||
 | 
					        let pl = manifest.store().get_song(self.id())?;
 | 
				
			||||||
 | 
					        Some(pl.url())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn url_as_str<'a, ST: store::BaseStore + Clone>(&self, manifest: &'a Manifest<ST>) -> Option<&'a str> {
 | 
				
			||||||
 | 
					        Some(self.url(manifest)?.as_str())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_url<ST: store::BaseStore + Clone>(&self, manifest: &mut Manifest<ST>, url: &Url) -> Option<()> {
 | 
				
			||||||
 | 
					        let pl = manifest.store_mut().get_song_mut(self.id())?;
 | 
				
			||||||
 | 
					        pl.set_url(url);
 | 
				
			||||||
 | 
					        Some(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_url_from_str<ST: store::BaseStore + Clone>(&self, manifest: &mut Manifest<ST>, url: &str) -> Option<()> {
 | 
				
			||||||
 | 
					        let Ok(url) = Url::from_str(url) else {return None};
 | 
				
			||||||
 | 
					        self.set_url(manifest, &url);
 | 
				
			||||||
 | 
					        Some(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn source_type<'a, ST: store::BaseStore + Clone>(&self, manifest: &'a Manifest<ST>) -> Option<&'a SourceType> {
 | 
				
			||||||
 | 
					        let pl = manifest.store().get_song(self.id())?;
 | 
				
			||||||
 | 
					        Some(pl.source_type())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_source_type<ST: store::BaseStore + Clone>(&self, manifest: &mut Manifest<ST>, source_type: &SourceType) -> Option<()> {
 | 
				
			||||||
 | 
					        let pl = manifest.store_mut().get_song_mut(self.id())?;
 | 
				
			||||||
 | 
					        pl.set_source_type(source_type);
 | 
				
			||||||
 | 
					        Some(())
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										69
									
								
								xmpd-manifest/src/song.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								xmpd-manifest/src/song.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,69 @@
 | 
				
			||||||
 | 
					use std::str::FromStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, PartialOrd)]
 | 
				
			||||||
 | 
					pub struct Song {
 | 
				
			||||||
 | 
					    name: String,
 | 
				
			||||||
 | 
					    author: String,
 | 
				
			||||||
 | 
					    url: url::Url,
 | 
				
			||||||
 | 
					    source_type: SourceType, 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Song {
 | 
				
			||||||
 | 
					    pub fn new(url: &url::Url) -> crate::Result<Self> {
 | 
				
			||||||
 | 
					        Ok(Self {
 | 
				
			||||||
 | 
					            name: String::default(),
 | 
				
			||||||
 | 
					            author: String::default(),
 | 
				
			||||||
 | 
					            source_type: SourceType::from_url(url)?,
 | 
				
			||||||
 | 
					            url: url.clone()
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn new_from_str(url: &str) -> crate::Result<Self> {
 | 
				
			||||||
 | 
					        Self::new(&url::Url::from_str(url)?)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn name(&self) -> &str {
 | 
				
			||||||
 | 
					        &self.name
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn author(&self) -> &str {
 | 
				
			||||||
 | 
					        &self.author
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn url(&self) -> &url::Url {
 | 
				
			||||||
 | 
					        &self.url
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn source_type(&self) -> &SourceType {
 | 
				
			||||||
 | 
					        &self.source_type
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_name(&mut self, v: &str) {
 | 
				
			||||||
 | 
					        self.name = v.to_string();
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					    pub fn set_author(&mut self, v: &str) {
 | 
				
			||||||
 | 
					        self.author = v.to_string();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_url(&mut self, v: &url::Url) {
 | 
				
			||||||
 | 
					        self.url.clone_from(v);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn set_source_type(&mut self, v: &SourceType) {
 | 
				
			||||||
 | 
					        self.source_type.clone_from(v);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, PartialOrd)]
 | 
				
			||||||
 | 
					pub enum SourceType {
 | 
				
			||||||
 | 
					    Youtube,
 | 
				
			||||||
 | 
					    Spotify,
 | 
				
			||||||
 | 
					    Soundcloud,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl SourceType {
 | 
				
			||||||
 | 
					    fn from_url(url: &url::Url) -> crate::Result<Self> {
 | 
				
			||||||
 | 
					        match url.host_str() {
 | 
				
			||||||
 | 
					            Some("youtube.com") | Some("youtu.be") => Ok(Self::Youtube),
 | 
				
			||||||
 | 
					            Some("open.spotify.com") => Ok(Self::Spotify),
 | 
				
			||||||
 | 
					            Some("soundcloud.com") |Some("on.soundcloud.com") => Ok(Self::Soundcloud),
 | 
				
			||||||
 | 
					            Some(host) => anyhow::bail!("Unknown host {host:?}"),
 | 
				
			||||||
 | 
					            None => anyhow::bail!("Unknown host: (none)"),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										71
									
								
								xmpd-manifest/src/store/json.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								xmpd-manifest/src/store/json.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,71 @@
 | 
				
			||||||
 | 
					use std::{collections::HashMap, path::PathBuf};
 | 
				
			||||||
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					use crate::{playlist::Playlist, song::Song};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DEFAULT_TEXT: &str = r#"{
 | 
				
			||||||
 | 
					  "songs": {},
 | 
				
			||||||
 | 
					  "playlists": {}
 | 
				
			||||||
 | 
					}"#;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
 | 
				
			||||||
 | 
					pub struct JsonStore {
 | 
				
			||||||
 | 
					    #[serde(skip)]
 | 
				
			||||||
 | 
					    original_path: PathBuf,
 | 
				
			||||||
 | 
					    songs: HashMap<Uuid, Song>,
 | 
				
			||||||
 | 
					    playlists: HashMap<Uuid, Playlist>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl super::BaseStore for JsonStore {
 | 
				
			||||||
 | 
					    fn get_default_file_contents() -> &'static str {
 | 
				
			||||||
 | 
					        &DEFAULT_TEXT
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_file_extension() -> &'static str {
 | 
				
			||||||
 | 
					        "json"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn empty() -> Self where Self: Sized {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            original_path: PathBuf::new(),
 | 
				
			||||||
 | 
					            songs: HashMap::default(),
 | 
				
			||||||
 | 
					            playlists: HashMap::default(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn to_bytes(&self) -> crate::Result<Vec<u8>> {
 | 
				
			||||||
 | 
					        let s = serde_json::to_vec_pretty(self)?;
 | 
				
			||||||
 | 
					        Ok(s)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn from_bytes(s: &[u8]) -> crate::Result<Self> where Self: Sized {
 | 
				
			||||||
 | 
					        let s: Self = serde_json::from_slice(s)?;
 | 
				
			||||||
 | 
					        Ok(s)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_songs(&self) -> &HashMap<Uuid, Song> {
 | 
				
			||||||
 | 
					        &self.songs
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_songs_mut(&mut self) -> &mut HashMap<Uuid, Song> {
 | 
				
			||||||
 | 
					        &mut self.songs
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_song(&self, id: &Uuid) -> Option<&Song> {
 | 
				
			||||||
 | 
					        self.songs.get(id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_song_mut(&mut self, id: &Uuid) -> Option<&mut Song> {
 | 
				
			||||||
 | 
					        self.songs.get_mut(id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_playlists(&self) -> &HashMap<Uuid, Playlist> {
 | 
				
			||||||
 | 
					        &self.playlists
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_playlists_mut(&mut self) -> &mut HashMap<Uuid, Playlist> {
 | 
				
			||||||
 | 
					        &mut self.playlists
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_playlist(&self, id: &Uuid) -> Option<&Playlist> {
 | 
				
			||||||
 | 
					        self.playlists.get(id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_playlist_mut(&mut self, id: &Uuid) -> Option<&mut Playlist> {
 | 
				
			||||||
 | 
					        self.playlists.get_mut(id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn save_original_path(&mut self, p: &std::path::Path) {
 | 
				
			||||||
 | 
					        self.original_path = p.to_path_buf(); 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_original_path(&self) -> &std::path::Path {
 | 
				
			||||||
 | 
					        &self.original_path
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								xmpd-manifest/src/store/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								xmpd-manifest/src/store/mod.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					use std::{collections::HashMap, path::Path};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::{playlist::Playlist, song::Song};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod json;
 | 
				
			||||||
 | 
					pub use json::JsonStore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub trait BaseStore { 
 | 
				
			||||||
 | 
					    fn get_songs(&self) -> &HashMap<Uuid, Song>;
 | 
				
			||||||
 | 
					    fn get_songs_mut(&mut self) -> &mut HashMap<Uuid, Song>;
 | 
				
			||||||
 | 
					    fn get_song(&self, id: &Uuid) -> Option<&Song>;
 | 
				
			||||||
 | 
					    fn get_song_mut(&mut self, id: &Uuid) -> Option<&mut Song>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn get_playlists(&self) -> &HashMap<Uuid, Playlist>;
 | 
				
			||||||
 | 
					    fn get_playlists_mut(&mut self) -> &mut HashMap<Uuid, Playlist>;
 | 
				
			||||||
 | 
					    fn get_playlist(&self, id: &Uuid) -> Option<&Playlist>;
 | 
				
			||||||
 | 
					    fn get_playlist_mut(&mut self, id: &Uuid) -> Option<&mut Playlist>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn to_bytes(&self) -> crate::Result<Vec<u8>>;
 | 
				
			||||||
 | 
					    fn from_bytes(s: &[u8]) -> crate::Result<Self> where Self: Sized;
 | 
				
			||||||
 | 
					    fn empty() -> Self where Self: Sized;
 | 
				
			||||||
 | 
					    fn save_to(&self, p: &Path) -> crate::Result<()> {
 | 
				
			||||||
 | 
					        let bin = self.to_bytes()?;
 | 
				
			||||||
 | 
					        std::fs::write(p, bin)?;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn load_from(&mut self, p: &Path) -> crate::Result<()> where Self: Clone {
 | 
				
			||||||
 | 
					        let bin = std::fs::read(p)?;
 | 
				
			||||||
 | 
					        let s = Self::from_bytes(&bin)?;
 | 
				
			||||||
 | 
					        self.clone_from(&s);
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_default_file_contents() -> &'static str;
 | 
				
			||||||
 | 
					    fn get_file_extension() -> &'static str;
 | 
				
			||||||
 | 
					    fn save_original_path(&mut self, p: &Path);
 | 
				
			||||||
 | 
					    fn get_original_path(&self) -> &Path;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								xmpd-manifest/src/tests/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								xmpd-manifest/src/tests/mod.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn manifest_creation_base<ST: crate::store::BaseStore + Clone>() {
 | 
				
			||||||
 | 
					    use crate::Manifest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut p = std::env::temp_dir();
 | 
				
			||||||
 | 
					    p.push("test_manifest");
 | 
				
			||||||
 | 
					    p.with_extension(ST::get_file_extension());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let manifest: Manifest<ST> = Manifest::new(&p).unwrap();
 | 
				
			||||||
 | 
					    manifest.save().unwrap();
 | 
				
			||||||
 | 
					    let content = std::fs::read_to_string(&p).unwrap();
 | 
				
			||||||
 | 
					    println!("{}", content);
 | 
				
			||||||
 | 
					    assert!(content == ST::get_default_file_contents().to_string());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					pub fn manifest_creation_json() {
 | 
				
			||||||
 | 
					    manifest_creation_base::<crate::store::JsonStore>();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user