Skip to main content

nix_compat/nix_daemon/
types.rs

1use crate::derived_path::DerivedPath;
2use crate::nixbase32;
3use crate::wire::de::Error;
4use crate::{
5    narinfo::Signature,
6    nixhash::CAHash,
7    store_path::StorePath,
8    wire::{
9        de::{NixDeserialize, NixRead},
10        ser::{NixSerialize, NixWrite},
11    },
12};
13use nix_compat_derive::{NixDeserialize, NixSerialize};
14
15/// Marker type that consumes/sends and ignores a u64.
16#[derive(Clone, Debug, NixDeserialize, NixSerialize)]
17#[nix(from = "u64", into = "u64")]
18pub struct IgnoredZero;
19impl From<u64> for IgnoredZero {
20    fn from(_: u64) -> Self {
21        IgnoredZero
22    }
23}
24
25impl From<IgnoredZero> for u64 {
26    fn from(_: IgnoredZero) -> Self {
27        0
28    }
29}
30
31#[derive(
32    Debug,
33    Clone,
34    Copy,
35    PartialEq,
36    Eq,
37    PartialOrd,
38    Ord,
39    Hash,
40    num_enum::TryFromPrimitive,
41    num_enum::IntoPrimitive,
42    NixDeserialize,
43    NixSerialize,
44)]
45#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
46#[nix(try_from = "u16", into = "u16")]
47#[repr(u16)]
48pub enum BuildMode {
49    Normal = 0,
50    Repair = 1,
51    Check = 2,
52}
53
54#[derive(Debug, NixSerialize)]
55pub struct TraceLine {
56    have_pos: IgnoredZero,
57    hint: String,
58}
59
60/// Represents an error returned by the nix-daemon to its client.
61///
62/// Adheres to the format described in serialization.md
63#[derive(NixSerialize)]
64pub struct NixError {
65    #[nix(version = "26..")]
66    type_: &'static str,
67
68    #[nix(version = "26..")]
69    level: u64,
70
71    #[nix(version = "26..")]
72    name: &'static str,
73
74    msg: String,
75    #[nix(version = "26..")]
76    have_pos: IgnoredZero,
77
78    #[nix(version = "26..")]
79    traces: Vec<TraceLine>,
80
81    #[nix(version = "..=25")]
82    exit_status: u64,
83}
84
85impl NixError {
86    pub fn new(msg: String) -> Self {
87        Self {
88            type_: "Error",
89            level: 0, // error
90            name: "Error",
91            msg,
92            have_pos: IgnoredZero {},
93            traces: vec![],
94            exit_status: 1,
95        }
96    }
97}
98
99impl NixSerialize for Option<UnkeyedValidPathInfo> {
100    async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
101    where
102        W: NixWrite,
103    {
104        match self {
105            Some(value) => {
106                writer.write_value(&true).await?;
107                writer.write_value(value).await
108            }
109            None => writer.write_value(&false).await,
110        }
111    }
112}
113
114#[derive(NixSerialize, NixDeserialize, Debug, Clone, PartialEq)]
115pub struct UnkeyedValidPathInfo {
116    pub deriver: Option<StorePath>,
117    pub nar_hash: NarHash,
118    pub references: Vec<StorePath>,
119    pub registration_time: u64,
120    pub nar_size: u64,
121    pub ultimate: bool,
122    pub signatures: Vec<Signature<String>>,
123    pub ca: Option<CAHash>,
124}
125
126/// Request tuple for [super::worker_protocol::Operation::QueryValidPaths]
127#[derive(NixDeserialize)]
128pub struct QueryValidPaths {
129    // Paths to query
130    pub paths: Vec<StorePath>,
131
132    // Whether to try and substitute the paths.
133    #[nix(version = "27..")]
134    pub substitute: bool,
135}
136
137/// Request tuple for [super::worker_protocol::Operation::BuildPaths]
138#[derive(NixDeserialize)]
139pub struct BuildPaths {
140    // Paths to build
141    pub paths: Vec<DerivedPath>,
142
143    // How to build the paths
144    pub mode: BuildMode,
145}
146
147/// newtype wrapper for the byte array that correctly implements NixSerialize, NixDeserialize.
148#[derive(Debug, Clone, Copy, PartialEq, Eq)]
149pub struct NarHash([u8; 32]);
150
151impl NarHash {
152    pub fn from_digest(digest: [u8; 32]) -> Self {
153        NarHash(digest)
154    }
155}
156
157impl std::ops::Deref for NarHash {
158    type Target = [u8; 32];
159
160    fn deref(&self) -> &Self::Target {
161        &self.0
162    }
163}
164
165impl NixDeserialize for NarHash {
166    async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
167    where
168        R: ?Sized + NixRead + Send,
169    {
170        if let Some(bytes) = reader.try_read_bytes().await? {
171            let result = data_encoding::HEXLOWER
172                .decode(bytes.as_ref())
173                .map_err(R::Error::invalid_data)?;
174            Ok(Some(NarHash(result.try_into().map_err(|_| {
175                R::Error::invalid_data("incorrect length")
176            })?)))
177        } else {
178            Ok(None)
179        }
180    }
181}
182
183impl NixSerialize for NarHash {
184    async fn serialize<W>(&self, writer: &mut W) -> Result<(), W::Error>
185    where
186        W: NixWrite,
187    {
188        nixbase32::encode(&self.0).serialize(writer).await
189    }
190}
191
192/// Info type used by [super::worker_protocol::Operation::AddToStoreNar] and [super::worker_protocol::Operation::AddMultipleToStore]
193///
194/// See: [ValidPathInfo reference](https://snix.dev/docs/reference/nix-daemon-protocol/types/#validpathinfo)
195#[derive(NixDeserialize, Debug)]
196pub struct ValidPathInfo {
197    // - path :: [StorePath][se-StorePath]
198    pub path: StorePath,
199    pub info: UnkeyedValidPathInfo,
200}