debian_watch/
lib.rs

1#![deny(missing_docs)]
2//! Formatting-preserving parser and editor for Debian watch files
3//!
4//! # Example
5//!
6//! ```rust
7//! let wf = debian_watch::WatchFile::new(None);
8//! assert_eq!(wf.version(), debian_watch::DEFAULT_VERSION);
9//! assert_eq!("", wf.to_string());
10//!
11//! let wf = debian_watch::WatchFile::new(Some(4));
12//! assert_eq!(wf.version(), 4);
13//! assert_eq!("version=4\n", wf.to_string());
14//!
15//! let wf: debian_watch::WatchFile = r#"version=4
16//! opts=foo=blah https://foo.com/bar .*/v?(\d\S+)\.tar\.gz
17//! "#.parse().unwrap();
18//! assert_eq!(wf.version(), 4);
19//! assert_eq!(wf.entries().collect::<Vec<_>>().len(), 1);
20//! let entry = wf.entries().next().unwrap();
21//! assert_eq!(entry.opts(), maplit::hashmap! {
22//!    "foo".to_string() => "blah".to_string(),
23//! });
24//! assert_eq!(&entry.url(), "https://foo.com/bar");
25//! assert_eq!(entry.matching_pattern().as_deref(), Some(".*/v?(\\d\\S+)\\.tar\\.gz"));
26//! ```
27
28mod convert;
29mod lex;
30mod parse;
31mod parse_v5;
32mod types_v5;
33
34/// Any watch files without a version are assumed to be
35/// version 1.
36pub const DEFAULT_VERSION: u32 = 1;
37
38mod traits;
39mod types;
40
41pub use traits::*;
42pub use types::*;
43
44/// Let's start with defining all kinds of tokens and
45/// composite nodes.
46#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
47#[allow(non_camel_case_types, missing_docs, clippy::upper_case_acronyms)]
48#[repr(u16)]
49pub(crate) enum SyntaxKind {
50    KEY = 0,
51    VALUE,
52    EQUALS,
53    QUOTE,
54    COMMA,
55    CONTINUATION,
56    NEWLINE,
57    WHITESPACE, // whitespaces is explicit
58    COMMENT,    // comments
59    ERROR,      // as well as errors
60
61    // composite nodes
62    ROOT,      // The entire file
63    VERSION,   // "version=x\n"
64    ENTRY,     // "opts=foo=blah https://foo.com/bar .*/v?(\d\S+)\.tar\.gz\n"
65    OPTS_LIST, // "opts=foo=blah"
66    OPTION,    // "foo=blah"
67}
68
69/// Convert our `SyntaxKind` into the rowan `SyntaxKind`.
70impl From<SyntaxKind> for rowan::SyntaxKind {
71    fn from(kind: SyntaxKind) -> Self {
72        Self(kind as u16)
73    }
74}
75
76pub use crate::convert::{convert_to_v5, ConversionError};
77pub use crate::parse::Entry;
78pub use crate::parse::WatchFile;
79pub use crate::parse::{parse_watch_file, Parse};
80pub use crate::parse_v5::{EntryV5, WatchFileV5};
81
82#[cfg(test)]
83mod tests {
84    #[test]
85    fn test_create_watchfile() {
86        let wf = super::WatchFile::new(None);
87        assert_eq!(wf.version(), super::DEFAULT_VERSION);
88
89        assert_eq!("", wf.to_string());
90
91        let wf = super::WatchFile::new(Some(4));
92        assert_eq!(wf.version(), 4);
93
94        assert_eq!("version=4\n", wf.to_string());
95    }
96}