uv_tool/
receipt.rs

1use std::path::Path;
2
3use serde::Deserialize;
4
5use crate::Tool;
6
7/// A `uv-receipt.toml` file tracking the installation of a tool.
8#[allow(dead_code)]
9#[derive(Debug, Clone, Deserialize)]
10pub struct ToolReceipt {
11    pub(crate) tool: Tool,
12
13    /// The raw unserialized document.
14    #[serde(skip)]
15    pub(crate) raw: String,
16}
17
18impl ToolReceipt {
19    /// Parse a [`ToolReceipt`] from a raw TOML string.
20    pub(crate) fn from_string(raw: String) -> Result<Self, toml::de::Error> {
21        let tool = toml::from_str(&raw)?;
22        Ok(Self { raw, ..tool })
23    }
24
25    ///  Read a [`ToolReceipt`] from the given path.
26    pub(crate) fn from_path(path: &Path) -> Result<Self, crate::Error> {
27        match fs_err::read_to_string(path) {
28            Ok(contents) => Ok(Self::from_string(contents)
29                .map_err(|err| crate::Error::ReceiptRead(path.to_owned(), Box::new(err)))?),
30            Err(err) => Err(err.into()),
31        }
32    }
33
34    /// Returns the TOML representation of this receipt.
35    pub(crate) fn to_toml(&self) -> Result<String, toml_edit::ser::Error> {
36        // We construct a TOML document manually instead of going through Serde to enable
37        // the use of inline tables.
38        let mut doc = toml_edit::DocumentMut::new();
39        doc.insert("tool", toml_edit::Item::Table(self.tool.to_toml()?));
40
41        Ok(doc.to_string())
42    }
43}
44
45impl From<Tool> for ToolReceipt {
46    fn from(tool: Tool) -> Self {
47        Self {
48            tool,
49            raw: String::new(),
50        }
51    }
52}