chrony_confile/ast/source_file.rs
1//! `.sources` file parsing types.
2//!
3//! Chrony uses `.sources` files (typically in `/var/lib/chrony`) to persist known NTP sources.
4//! This module provides lenient parsing that silently skips erroneous lines.
5
6use crate::ast::source::{PeerConfig, PoolConfig, ServerConfig};
7
8/// A single source entry in a `.sources` file.
9///
10/// Each entry is one of `server`, `pool`, or `peer` with its full configuration.
11#[derive(Debug, Clone, PartialEq)]
12pub enum SourceEntry {
13 /// A `server` directive entry.
14 Server(ServerConfig),
15 /// A `pool` directive entry.
16 Pool(PoolConfig),
17 /// A `peer` directive entry.
18 Peer(PeerConfig),
19}
20
21/// A single node in a `.sources` file.
22///
23/// Analogous to [`ConfigNode`](crate::ConfigNode) but limited to server/pool/peer entries.
24#[derive(Debug, Clone, PartialEq)]
25pub enum SourceNode {
26 /// A source entry (server, pool, or peer).
27 Entry(SourceEntry),
28 /// A comment line.
29 Comment(String),
30 /// An empty or whitespace-only line.
31 BlankLine,
32}
33
34/// A parsed `.sources` file.
35///
36/// Chrony writes `.sources` files to persist known NTP sources. Unlike the main
37/// configuration parser, this parser is always lenient: unparseable lines and
38/// unknown directives are silently skipped.
39///
40/// # Examples
41///
42/// ## Parsing via `parse()`
43///
44/// ```rust
45/// use chrony_confile::SourceFile;
46///
47/// let sources = SourceFile::parse("\
48/// server ntp1.example.com iburst
49/// pool pool.ntp.org maxsources 6
50/// ");
51///
52/// assert_eq!(sources.nodes.len(), 2);
53/// ```
54///
55/// ## Parsing via `FromStr`
56///
57/// ```rust
58/// use chrony_confile::SourceFile;
59///
60/// let sources: SourceFile = "\
61/// server ntp1.example.com
62/// peer 192.168.1.1
63/// ".parse().unwrap();
64///
65/// assert_eq!(sources.nodes.len(), 2);
66/// ```
67#[derive(Debug, Clone, Default, PartialEq)]
68pub struct SourceFile {
69 /// The ordered list of source nodes.
70 pub nodes: Vec<SourceNode>,
71}
72
73impl std::str::FromStr for SourceFile {
74 type Err = std::convert::Infallible;
75
76 fn from_str(s: &str) -> Result<Self, Self::Err> {
77 Ok(Self::parse(s))
78 }
79}