caddyfile_rs/lib.rs
1//! Caddyfile lexer, parser, formatter, and builder.
2//!
3//! A typed AST for Caddy's configuration file format with tools
4//! to parse Caddyfiles from text, build them programmatically,
5//! and format them back to valid syntax.
6//!
7//! # Quick start
8//!
9//! ## Parse and re-format a Caddyfile
10//!
11//! ```
12//! use caddyfile_rs::{tokenize, parse, format};
13//!
14//! let input = "example.com {\n\treverse_proxy app:3000\n}\n";
15//! let tokens = tokenize(input).unwrap();
16//! let caddyfile = parse(&tokens).unwrap();
17//! let output = format(&caddyfile);
18//! assert_eq!(output, input);
19//! ```
20//!
21//! ## Build a Caddyfile programmatically
22//!
23//! ```
24//! use caddyfile_rs::{Caddyfile, SiteBlock, Directive, format};
25//!
26//! let cf = Caddyfile::new()
27//! .site(SiteBlock::new("example.com")
28//! .reverse_proxy("app:3000")
29//! .encode_gzip()
30//! .log());
31//!
32//! let output = format(&cf);
33//! assert!(output.contains("reverse_proxy app:3000"));
34//! ```
35
36// Allow noisy pedantic lints that don't add value for
37// a library crate.
38#![allow(
39 clippy::missing_errors_doc,
40 clippy::missing_panics_doc,
41 clippy::module_name_repetitions
42)]
43
44pub mod ast;
45pub mod builder;
46pub mod formatter;
47pub mod lexer;
48pub mod parser;
49pub mod token;
50
51pub use ast::{
52 Address, Argument, Caddyfile, Directive, GlobalOptions, Matcher, NamedRoute, Scheme, SiteBlock,
53 Snippet, parse_address,
54};
55pub use formatter::format;
56pub use lexer::{LexError, LexErrorKind, tokenize};
57pub use parser::{ParseError, ParseErrorKind, parse};
58pub use token::{Span, Token, TokenKind};
59
60/// Unified error type covering both lexing and parsing.
61#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
62pub enum Error {
63 /// A lexer error.
64 #[error("{0}")]
65 Lex(#[from] LexError),
66 /// A parser error.
67 #[error("{0}")]
68 Parse(#[from] ParseError),
69}
70
71/// Tokenize and parse a Caddyfile source string in one step.
72pub fn parse_str(input: &str) -> Result<Caddyfile, Error> {
73 let tokens = tokenize(input)?;
74 Ok(parse(&tokens)?)
75}