2026-03-22 17:15:04 +01:00
|
|
|
use std::ops::Deref;
|
|
|
|
|
|
|
|
|
|
use crate::prelude::*;
|
|
|
|
|
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
|
|
|
|
mod impls;
|
|
|
|
|
|
|
|
|
|
/// Unfortunately, empty-string identifiers are valid Nix...
|
|
|
|
|
///
|
|
|
|
|
/// This type does not provide a [`Default`] impl, however.
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
|
|
|
#[derive(Deserialize, Serialize)]
|
|
|
|
|
#[serde(untagged)]
|
|
|
|
|
pub enum ConvenientAttrPath {
|
|
|
|
|
Dotted(Box<str>),
|
|
|
|
|
Split(Box<[Box<str>]>),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ConvenientAttrPath {
|
|
|
|
|
pub fn clone_from_dotted(s: &str) -> Self {
|
|
|
|
|
Self::Dotted(Box::from(s))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn clone_from_split(s: &[&str]) -> Self {
|
|
|
|
|
Self::from_str_iter(s.iter().map(Deref::deref))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn from_str_iter<'i, I>(iter: I) -> Self
|
|
|
|
|
where
|
|
|
|
|
I: IntoIterator<Item = &'i str>,
|
|
|
|
|
{
|
|
|
|
|
let iter = iter.into_iter();
|
|
|
|
|
let boxed = iter.map(Box::from);
|
|
|
|
|
Self::Split(Box::from_iter(boxed))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn to_nix_decl(&self) -> Box<str> {
|
|
|
|
|
use ConvenientAttrPath::*;
|
|
|
|
|
match self {
|
|
|
|
|
Dotted(s) => s.clone(),
|
|
|
|
|
Split(path) => {
|
|
|
|
|
// FIXME: quote if necessary
|
|
|
|
|
path.join(".").into_boxed_str()
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-22 17:15:04 +01:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
|
#[derive(Deserialize, Serialize)]
|
|
|
|
|
#[serde(untagged)]
|
|
|
|
|
pub enum NixLiteral {
|
|
|
|
|
String(String),
|
|
|
|
|
Number(f64),
|
|
|
|
|
// FIXME: add the rest =P
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl NixLiteral {
|
|
|
|
|
pub fn to_nix_source(&self) -> String {
|
|
|
|
|
match self {
|
|
|
|
|
NixLiteral::String(s) => format!("\"{s}\""),
|
|
|
|
|
NixLiteral::Number(n) => n.to_string(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-22 17:15:04 +01:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
|
#[derive(serde::Deserialize, serde::Serialize)]
|
|
|
|
|
#[serde(tag = "action", content = "args", rename_all = "snake_case")]
|
|
|
|
|
// FIXME: rename to not confuse with the clap argument type.
|
|
|
|
|
pub enum DaemonCmd {
|
|
|
|
|
Append {
|
|
|
|
|
name: ConvenientAttrPath,
|
2026-03-22 17:15:04 +01:00
|
|
|
value: Box<NixLiteral>,
|
2026-03-22 17:15:04 +01:00
|
|
|
},
|
|
|
|
|
}
|