aboutsummaryrefslogtreecommitdiffstats
path: root/src/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/config')
-rw-r--r--src/config/helpers.rs44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/config/helpers.rs b/src/config/helpers.rs
index ddf29ad..edf4bd5 100644
--- a/src/config/helpers.rs
+++ b/src/config/helpers.rs
@@ -1,8 +1,13 @@
// SPDX-FileCopyrightText: 2025 Tomasz Kramkowski <tomasz@kramkow.ski>
// SPDX-License-Identifier: GPL-3.0-or-later
-use std::time::Duration;
+use std::{
+ ffi::{OsStr, OsString},
+ os::unix::ffi::OsStrExt,
+ time::Duration,
+};
+use base64::{engine::general_purpose::STANDARD, Engine as _};
use rumqttc::QoS;
use serde::{de, Deserialize, Deserializer};
@@ -79,12 +84,44 @@ where
Ok(helper.map(|Helper(external)| external))
}
+pub fn deserialize_box_slice_os_string<'de, D>(deserializer: D) -> Result<Box<[OsString]>, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ #[derive(Deserialize)]
+ #[serde(untagged)]
+ enum Untagged {
+ String(String),
+ Base64 { b64: String },
+ }
+
+ impl TryInto<OsString> for Untagged {
+ type Error = String;
+ fn try_into(self) -> Result<OsString, Self::Error> {
+ match self {
+ Untagged::String(s) => Ok(s.into()),
+ Untagged::Base64 { b64 } => match STANDARD.decode(&b64) {
+ Err(_) => Err(b64),
+ Ok(b) => Ok(OsStr::from_bytes(&b).to_owned()),
+ },
+ }
+ }
+ }
+
+ Vec::<Untagged>::deserialize(deserializer)?
+ .into_iter()
+ .map(TryInto::<OsString>::try_into)
+ .collect::<Result<_, _>>()
+ .map_err(|e| de::Error::invalid_value(de::Unexpected::Str(&e), &"valid Base64"))
+}
+
impl<'de> Deserialize<'de> for super::Program {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(remote = "super::Program")]
struct Helper {
- command: Box<[String]>,
+ #[serde(deserialize_with = "deserialize_box_slice_os_string")]
+ command: Box<[OsString]>,
#[serde(default, deserialize_with = "deserialize_timeout_opt")]
timeout: Option<Duration>,
}
@@ -92,7 +129,8 @@ impl<'de> Deserialize<'de> for super::Program {
#[derive(Deserialize)]
#[serde(untagged)]
enum Untagged {
- Short(Box<[String]>),
+ #[serde(deserialize_with = "deserialize_box_slice_os_string")]
+ Short(Box<[OsString]>),
#[serde(with = "Helper")]
Full(super::Program),
}