1use std::path::Path;
9use std::sync::Arc;
10
11use crate::JsonCodec;
12#[cfg(feature = "toml")]
13use crate::TomlCodec;
14use crate::codec::Codec;
15
16#[must_use]
19pub fn codec_for_name(name: &str) -> Option<Arc<dyn Codec>> {
20 match name.to_ascii_lowercase().as_str() {
21 #[cfg(feature = "toml")]
22 "toml" => Some(Arc::new(TomlCodec)),
23 "json" => Some(Arc::new(JsonCodec::default())),
24 _ => None,
25 }
26}
27
28#[must_use]
31pub fn codec_for_path(path: &Path) -> Option<Arc<dyn Codec>> {
32 let ext = path.extension().and_then(|ext| ext.to_str())?;
33 codec_for_name(ext)
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn selects_json_by_name_and_path() {
42 assert_eq!(codec_for_name("json").unwrap().name(), "json");
43 assert_eq!(codec_for_name("JSON").unwrap().name(), "json");
44 assert_eq!(
45 codec_for_path(Path::new("/etc/app/config.json"))
46 .unwrap()
47 .name(),
48 "json"
49 );
50 }
51
52 #[cfg(feature = "toml")]
53 #[test]
54 fn selects_toml_by_name_and_path() {
55 assert_eq!(codec_for_name("toml").unwrap().name(), "toml");
56 assert_eq!(
57 codec_for_path(Path::new("config.toml")).unwrap().name(),
58 "toml"
59 );
60 }
61
62 #[test]
63 fn returns_none_for_unknown_or_missing_extension() {
64 assert!(codec_for_name("yaml").is_none());
65 assert!(codec_for_path(Path::new("config")).is_none());
66 }
67}