1#![doc = include_str!("../README.md")]
2#![deny(missing_docs)]
3
4mod parser;
5pub mod table;
6mod text;
7pub mod types;
8
9use {
10 crate::table::TomlTable,
11 std::{
12 fmt::{Debug, Display},
13 ops::Deref,
14 },
15 text::Span,
16};
17
18pub fn parse(str: &str) -> Result<Toml<'_>, TomlError> {
20 parser::parse_str(str)
21}
22
23#[derive(Debug)]
25pub struct Toml<'a> {
26 source: &'a str,
27 table: TomlTable<'a>,
28}
29impl<'a> Toml<'a> {
30 pub fn new(str: &'a str) -> Result<Self, TomlError<'a>> {
32 parser::parse_str(str)
33 }
34 pub fn parse(str: &'a str) -> Result<Self, TomlError<'a>> {
36 parser::parse_str(str)
37 }
38
39 pub fn source(&self) -> &str {
41 self.source
42 }
43}
44impl<'a> From<Toml<'a>> for TomlTable<'a> {
45 fn from(value: Toml<'a>) -> TomlTable<'a> {
46 value.table
47 }
48}
49impl<'a> Deref for Toml<'a> {
50 type Target = TomlTable<'a>;
51
52 fn deref(&self) -> &Self::Target {
53 &self.table
54 }
55}
56
57pub struct TomlError<'a> {
59 pub src: Span<'a>,
61 pub kind: TomlErrorKind,
63}
64impl Debug for TomlError<'_> {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 let mut start = self.src.source[..self.src.start].bytes().enumerate().rev();
67 let mut newlines = 3u8;
68 while newlines != 0 {
69 match start.next() {
70 None => break,
71 Some((_, b'\n')) => newlines -= 1,
72 _ => {}
73 }
74 }
75 let start = start.next().map(|(idx, _)| idx + 2).unwrap_or(0);
76
77 let mut end = self.src.source[self.src.end..].bytes().enumerate();
78 let mut newlines = 3u8;
79 while newlines != 0 {
80 match end.next() {
81 None => break,
82 Some((_, b'\n')) => newlines -= 1,
83 _ => {}
84 }
85 }
86 let end = end
87 .next()
88 .map(|(idx, _)| self.src.end + idx - 1)
89 .unwrap_or(self.src.source.len());
90
91 write!(
92 f,
93 "Error: {:?} at `{}`\nIn:\n{}",
94 self.kind,
95 self.src.as_str(),
96 &self.src.source[start..end]
97 )
98 }
99}
100impl Display for TomlError<'_> {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 write!(f, "{self:?}")
103 }
104}
105#[derive(Debug, PartialEq, Eq)]
107pub enum TomlErrorKind {
108 InvalidBareKey,
110 BareKeyHasSpace,
112 NoEqualsInAssignment,
114 NoKeyInAssignment,
116 NoValueInAssignment,
118 UnclosedBasicString,
120 UnclosedLiteralString,
122 UnclosedQuotedKey,
124 UnrecognisedValue,
126 ReusedKey,
128 NumberTooLarge,
131 NumberHasInvalidBase,
134 NumberHasLeadingZero,
136 InvalidNumber,
138 UnknownEscapeSequence,
140 UnknownUnicodeScalar,
142 UnclosedTableBracket,
144 UnclosedInlineTableBracket,
146 UnclosedArrayOfTablesBracket,
148 UnclosedArrayBracket,
150 NoCommaDelimeter,
152 DateTimeTooManyDigits,
155 DateMissingMonth,
157 DateMissingDay,
159 DateMissingDash,
161 TimeMissingMinute,
163 TimeMissingSecond,
165 TimeMissingColon,
167 OffsetMissingHour,
169 OffsetMissingMinute,
171}
172
173pub mod prelude {
175 pub use crate::{
176 table::{TomlGetError, TomlTable},
177 types::{TomlValue, TomlValueType},
178 Toml, TomlError, TomlErrorKind,
179 };
180}