cargo_toml2/
lib.rs

1#![warn(clippy::all)]
2#![warn(clippy::pedantic)]
3mod config;
4mod manifest;
5pub use self::{config::*, manifest::*};
6
7use serde::{de::DeserializeOwned, ser::Serialize};
8use std::{io::Error as IoError, path::Path, result::Result};
9use toml::{de::Error, ser::Error as TomlError};
10
11#[derive(Debug)]
12pub struct CargoTomlError {
13    inner: ErrorKind,
14}
15
16impl std::fmt::Display for CargoTomlError {
17    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
18        write!(f, "{:?}", self.inner)
19    }
20}
21
22impl std::error::Error for CargoTomlError {
23    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
24        match &self.inner {
25            ErrorKind::Parse(e) => Some(e),
26            ErrorKind::Serialize(e) => Some(e),
27            ErrorKind::Io(e) => Some(e),
28        }
29    }
30}
31
32impl From<Error> for CargoTomlError {
33    fn from(e: Error) -> Self {
34        Self {
35            inner: ErrorKind::Parse(e),
36        }
37    }
38}
39
40impl From<IoError> for CargoTomlError {
41    fn from(e: IoError) -> Self {
42        Self {
43            inner: ErrorKind::Io(e),
44        }
45    }
46}
47
48impl From<TomlError> for CargoTomlError {
49    fn from(e: TomlError) -> Self {
50        Self {
51            inner: ErrorKind::Serialize(e),
52        }
53    }
54}
55
56#[derive(Debug)]
57enum ErrorKind {
58    Parse(Error),
59    Serialize(TomlError),
60    Io(IoError),
61}
62
63/// Reads the file at `path`.
64///
65/// # Examples
66///
67/// ```rust
68/// # use cargo_toml2::CargoToml;
69/// # use cargo_toml2::from_path;
70/// // Reading a CargoToml
71/// let toml: CargoToml = from_path("Cargo.toml").expect("Failed to read Cargo.toml");
72/// ```
73///
74/// # Errors
75///
76/// If reading the provided `path` fails, or deserialization fails.
77pub fn from_path<T: AsRef<Path>, R: DeserializeOwned>(path: T) -> Result<R, CargoTomlError> {
78    let path = path.as_ref();
79    let toml = std::fs::read_to_string(path)?;
80    let x: R = toml::from_str(&toml)?;
81    Ok(x)
82}
83
84/// Writes a serializable struct to the file at `path`.
85///
86/// # Examples
87///
88/// Re-serializing
89///
90/// ```rust
91/// # use cargo_toml2::CargoToml;
92/// # use cargo_toml2::from_path;
93/// # use cargo_toml2::to_path;
94/// // Writing a CargoToml
95/// let toml: CargoToml = from_path("Cargo.toml").expect("Failed to read Cargo.toml");
96/// to_path("Test.toml", toml).expect("Failed to serialize/write CargoToml");
97/// ```
98///
99/// Creating a new Cargo.toml
100///
101/// ```rust
102/// # use cargo_toml2::CargoToml;
103/// # use cargo_toml2::Package;
104/// # use cargo_toml2::from_path;
105/// # use cargo_toml2::to_path;
106/// let toml = CargoToml {
107///    package: Package {
108///        name: "Example".into(),
109///        version: "0.1.0".into(),
110///        authors: vec!["Namey McNameface".into()],
111///        ..Default::default()
112///    },
113///    ..Default::default()
114/// };
115/// to_path("Test.toml", toml).expect("Failed to serialize/write CargoToml");
116/// ```
117///
118/// # Errors
119///
120/// If writing to the provided `path` fails, or serialization fails.
121pub fn to_path<T: AsRef<Path>, R: Serialize>(path: T, save: R) -> Result<(), CargoTomlError> {
122    let path = path.as_ref();
123    let toml = toml::to_string(&save)?;
124    std::fs::write(path, toml)?;
125    Ok(())
126}