Skip to main content

stremio_addon_core/
config.rs

1use percent_encoding::percent_decode_str;
2use serde::{Deserialize, Serialize};
3use serde_json::{Map, Value};
4use thiserror::Error;
5
6#[derive(Clone, Debug, Default, Deserialize, Serialize)]
7#[serde(rename_all = "camelCase")]
8pub struct UserConfig {
9    #[serde(default, skip_serializing_if = "Option::is_none")]
10    pub auth_key: Option<String>,
11    #[serde(default, skip_serializing_if = "Option::is_none")]
12    pub enable_search: Option<bool>,
13    #[serde(flatten)]
14    pub extra: Map<String, Value>,
15}
16
17#[derive(Debug, Error)]
18pub enum ConfigError {
19    #[error("config path is not valid utf-8")]
20    InvalidUtf8,
21    #[error("config path is not valid json: {0}")]
22    InvalidJson(serde_json::Error),
23}
24
25pub fn decode_config_segment(segment: &str) -> Result<UserConfig, ConfigError> {
26    let decoded = percent_decode_str(segment)
27        .decode_utf8()
28        .map_err(|_| ConfigError::InvalidUtf8)?;
29    serde_json::from_str(&decoded).map_err(ConfigError::InvalidJson)
30}
31
32pub fn strip_json_suffix(value: &str) -> &str {
33    value.strip_suffix(".json").unwrap_or(value)
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn decodes_encoded_config() {
42        let cfg = decode_config_segment("%7B%22authKey%22%3A%22secret%22%7D").unwrap();
43        assert_eq!(cfg.auth_key.as_deref(), Some("secret"));
44    }
45
46    #[test]
47    fn preserves_unknown_fields() {
48        let cfg =
49            decode_config_segment("%7B%22authKey%22%3A%22secret%22%2C%22x%22%3A1%7D").unwrap();
50        assert_eq!(cfg.extra.get("x").and_then(Value::as_i64), Some(1));
51    }
52}