use serde::de::{MapAccess, SeqAccess, Visitor};
use serde::{Deserialize, Deserializer, Serialize};
use crate::{
HookLifecycle, HookName, OptionName, OptionScopeSelector, ScopeSelector, SetOptionMode,
};
use super::compat::{compat_next_element, required_next};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SetEnvironmentMode {
Set,
Clear,
Unset,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SetOptionRequest {
pub scope: ScopeSelector,
pub option: OptionName,
pub value: String,
pub mode: SetOptionMode,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct SetOptionByNameRequest {
pub scope: OptionScopeSelector,
pub name: String,
pub value: Option<String>,
pub mode: SetOptionMode,
pub only_if_unset: bool,
pub unset: bool,
pub unset_pane_overrides: bool,
#[serde(default)]
pub format: bool,
#[serde(default)]
pub format_target: Option<crate::Target>,
}
impl<'de> Deserialize<'de> for SetOptionByNameRequest {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_struct(
"SetOptionByNameRequest",
&[
"scope",
"name",
"value",
"mode",
"only_if_unset",
"unset",
"unset_pane_overrides",
"format",
"format_target",
],
SetOptionByNameRequestVisitor,
)
}
}
struct SetOptionByNameRequestVisitor;
impl<'de> Visitor<'de> for SetOptionByNameRequestVisitor {
type Value = SetOptionByNameRequest;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("a set-option-by-name request")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let scope = required_next(&mut seq, 0, &self)?;
let name = required_next(&mut seq, 1, &self)?;
let value = required_next(&mut seq, 2, &self)?;
let mode = required_next(&mut seq, 3, &self)?;
let only_if_unset = required_next(&mut seq, 4, &self)?;
let unset = required_next(&mut seq, 5, &self)?;
let unset_pane_overrides = required_next(&mut seq, 6, &self)?;
let format = compat_next_element(&mut seq)?;
let format_target = compat_next_element(&mut seq)?;
Ok(SetOptionByNameRequest {
scope,
name,
value,
mode,
only_if_unset,
unset,
unset_pane_overrides,
format,
format_target,
})
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut scope = None;
let mut name = None;
let mut value = None;
let mut mode = None;
let mut only_if_unset = None;
let mut unset = None;
let mut unset_pane_overrides = None;
let mut format = None;
let mut format_target = None;
while let Some(key) = map.next_key::<String>()? {
match key.as_str() {
"scope" => scope = Some(map.next_value()?),
"name" => name = Some(map.next_value()?),
"value" => value = Some(map.next_value()?),
"mode" => mode = Some(map.next_value()?),
"only_if_unset" => only_if_unset = Some(map.next_value()?),
"unset" => unset = Some(map.next_value()?),
"unset_pane_overrides" => unset_pane_overrides = Some(map.next_value()?),
"format" => format = Some(map.next_value()?),
"format_target" => format_target = Some(map.next_value()?),
_ => {
let _ = map.next_value::<serde::de::IgnoredAny>()?;
}
}
}
Ok(SetOptionByNameRequest {
scope: scope.ok_or_else(|| serde::de::Error::missing_field("scope"))?,
name: name.ok_or_else(|| serde::de::Error::missing_field("name"))?,
value: value.ok_or_else(|| serde::de::Error::missing_field("value"))?,
mode: mode.ok_or_else(|| serde::de::Error::missing_field("mode"))?,
only_if_unset: only_if_unset
.ok_or_else(|| serde::de::Error::missing_field("only_if_unset"))?,
unset: unset.ok_or_else(|| serde::de::Error::missing_field("unset"))?,
unset_pane_overrides: unset_pane_overrides
.ok_or_else(|| serde::de::Error::missing_field("unset_pane_overrides"))?,
format: format.unwrap_or(false),
format_target: format_target.unwrap_or(None),
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SetEnvironmentRequest {
pub scope: ScopeSelector,
pub name: String,
pub value: String,
#[serde(default)]
pub mode: Option<SetEnvironmentMode>,
#[serde(default)]
pub hidden: bool,
#[serde(default)]
pub format: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SetHookRequest {
pub scope: ScopeSelector,
pub hook: HookName,
pub command: String,
pub lifecycle: HookLifecycle,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SetHookMutationRequest {
pub scope: ScopeSelector,
pub hook: HookName,
pub command: Option<String>,
pub lifecycle: HookLifecycle,
pub append: bool,
pub unset: bool,
pub run_immediately: bool,
pub index: Option<u32>,
}