json_gettext/common/
json_get_text_builder.rs1use std::{collections::HashMap, fs::File, path::Path};
2
3use serde::Serialize;
4use serde_json::{Map, Value};
5
6use super::{Context, IntoKey, JSONGetText};
7use crate::{JSONGetTextBuildError, JSONGetTextValue};
8
9#[derive(Debug, Clone)]
11pub struct JSONGetTextBuilder<'a> {
12 default_key: crate::Key,
13 context: Context<'a>,
14 allow_extra_texts: bool,
15}
16
17impl<'a> JSONGetTextBuilder<'a> {
18 #[inline]
20 pub fn new<K: IntoKey>(default_key: K) -> JSONGetTextBuilder<'a> {
21 JSONGetTextBuilder {
22 default_key: default_key.into_key(),
23 context: HashMap::new(),
24 allow_extra_texts: false,
25 }
26 }
27
28 #[inline]
31 pub fn allow_extra_texts(&mut self, allow: bool) -> &mut Self {
32 self.allow_extra_texts = allow;
33
34 self
35 }
36
37 pub fn add_json<K: IntoKey, J: AsRef<str> + ?Sized>(
39 &mut self,
40 key: K,
41 json: &'a J,
42 ) -> Result<&mut Self, JSONGetTextBuildError> {
43 let key = key.into_key();
44
45 if self.context.contains_key(&key) {
46 return Err(JSONGetTextBuildError::DuplicatedKey(key));
47 }
48
49 let map: HashMap<String, JSONGetTextValue<'a>> = serde_json::from_str(json.as_ref())?;
50
51 self.context.insert(key, map);
52
53 Ok(self)
54 }
55
56 pub fn add_json_owned<K: IntoKey, J: AsRef<str>>(
58 &mut self,
59 key: K,
60 json: J,
61 ) -> Result<&mut Self, JSONGetTextBuildError> {
62 let key = key.into_key();
63
64 if self.context.contains_key(&key) {
65 return Err(JSONGetTextBuildError::DuplicatedKey(key));
66 }
67
68 let value: Map<String, Value> = serde_json::from_str(json.as_ref())?;
69
70 let mut map: HashMap<String, JSONGetTextValue<'static>> =
71 HashMap::with_capacity(value.len());
72
73 for (k, v) in value {
74 map.insert(k, JSONGetTextValue::from_json_value(v));
75 }
76
77 self.context.insert(key, map);
78
79 Ok(self)
80 }
81
82 pub fn add_json_file<K: IntoKey, P: AsRef<Path>>(
84 &mut self,
85 key: K,
86 path: P,
87 ) -> Result<&mut Self, JSONGetTextBuildError> {
88 let key = key.into_key();
89
90 if self.context.contains_key(&key) {
91 return Err(JSONGetTextBuildError::DuplicatedKey(key));
92 }
93
94 let path = path.as_ref();
95
96 let value: Map<String, Value> = serde_json::from_reader(File::open(path)?)?;
97
98 let mut map: HashMap<String, JSONGetTextValue<'static>> =
99 HashMap::with_capacity(value.len());
100
101 for (k, v) in value {
102 map.insert(k, JSONGetTextValue::from_json_value(v));
103 }
104
105 self.context.insert(key, map);
106
107 Ok(self)
108 }
109
110 pub fn add_serialize<K: IntoKey, S: Serialize>(
112 &mut self,
113 key: K,
114 value: S,
115 ) -> Result<&mut Self, JSONGetTextBuildError> {
116 let key = key.into_key();
117
118 if self.context.contains_key(&key) {
119 return Err(JSONGetTextBuildError::DuplicatedKey(key));
120 }
121
122 let value: Value = serde_json::to_value(value)?;
123
124 match value {
125 Value::Object(value) => {
126 let mut map: HashMap<String, JSONGetTextValue<'static>> =
127 HashMap::with_capacity(value.len());
128
129 for (k, v) in value {
130 map.insert(k, JSONGetTextValue::from_json_value(v));
131 }
132
133 self.context.insert(key, map);
134
135 Ok(self)
136 },
137 _ => Err(JSONGetTextBuildError::NotObject),
138 }
139 }
140
141 pub fn add_map<K: IntoKey>(
143 &mut self,
144 key: K,
145 map: HashMap<String, JSONGetTextValue<'a>>,
146 ) -> Result<&mut Self, JSONGetTextBuildError> {
147 let key = key.into_key();
148
149 if self.context.contains_key(&key) {
150 return Err(JSONGetTextBuildError::DuplicatedKey(key));
151 }
152
153 self.context.insert(key, map);
154
155 Ok(self)
156 }
157
158 pub fn build(self) -> Result<JSONGetText<'a>, JSONGetTextBuildError> {
160 JSONGetText::from_context_with_default_key(
161 self.default_key,
162 self.context,
163 self.allow_extra_texts,
164 )
165 }
166}
167
168impl<'a> From<crate::Key> for JSONGetTextBuilder<'a> {
169 #[inline]
170 fn from(v: crate::Key) -> JSONGetTextBuilder<'a> {
171 JSONGetTextBuilder::new(v)
172 }
173}