miau/configuration/
key.rs1use crate::{error::ConfigurationError, parsing};
2use serde::{Deserialize, Serialize};
3use std::convert::TryFrom;
4use std::ops::Deref;
5use std::{convert::From, fmt};
6
7#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Hash)]
14#[serde(transparent)]
15pub struct CompoundKey(Vec<Key>);
16
17#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Hash)]
21#[serde(untagged)]
22pub enum Key {
23 Array(usize),
25 Map(String),
27}
28
29impl CompoundKey {
30 pub fn new(keys: Vec<Key>) -> Self {
32 CompoundKey(keys)
33 }
34}
35
36impl Key {
37 pub fn unwrap_map(&self) -> String {
42 match self {
43 Key::Array(_) => panic!("Expected key to be map key!"),
44 Key::Map(s) => s.clone(),
45 }
46 }
47 pub fn unwrap_array(&self) -> usize {
52 match self {
53 Key::Array(i) => *i,
54 Key::Map(_) => panic!("Expected key to be array key!"),
55 }
56 }
57}
58
59impl Deref for CompoundKey {
60 type Target = Vec<Key>;
61
62 fn deref(&self) -> &Self::Target {
63 &self.0
64 }
65}
66
67impl From<Vec<Key>> for CompoundKey {
68 fn from(keys: Vec<Key>) -> Self {
69 CompoundKey::new(keys)
70 }
71}
72
73impl TryFrom<&str> for CompoundKey {
74 type Error = ConfigurationError;
75
76 fn try_from(value: &str) -> Result<Self, Self::Error> {
77 parsing::str_to_key(value)
78 .map_err(|e| e.enrich_with_context(format!("Parsing key `{}` failed", value)))
79 }
80}
81
82impl TryFrom<String> for CompoundKey {
83 type Error = ConfigurationError;
84
85 fn try_from(value: String) -> Result<Self, Self::Error> {
86 parsing::str_to_key(value.as_ref())
87 .map_err(|e| e.enrich_with_context(format!("Parsing key `{}` failed", value)))
88 }
89}
90
91impl fmt::Display for Key {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 match self {
94 Key::Array(i) => write!(f, "[{}]", i),
95 Key::Map(k) => write!(f, "{}", k),
96 }
97 }
98}
99
100impl From<String> for Key {
101 fn from(v: String) -> Self {
102 Key::Map(v)
103 }
104}
105
106impl From<&str> for Key {
107 fn from(v: &str) -> Self {
108 Key::Map(v.to_string())
109 }
110}
111
112macro_rules! impl_key_from {
113 ($($t:ty),*) => {
114 $(impl From<$t> for Key {
115 fn from(v: $t) -> Self {
116 Key::Array(v as usize)
117 }
118 })*
119 };
120}
121
122impl_key_from!(u8, u16, u32, u64, usize);