gix_config/parse/
event.rs1use std::fmt::Display;
2
3use bstr::{BStr, BString};
4
5use crate::parse::{Event, EventRef};
6
7impl Event {
8 pub(crate) fn rebase(&mut self, offset: usize) -> Result<(), crate::parse::span::Error> {
10 match self {
11 Event::Comment(comment) => comment.text.rebase(offset),
12 Event::SectionHeader(header) => header.rebase(offset),
13 Event::SectionValueName(name) => name.rebase(offset),
14 Event::Value(bytes)
15 | Event::Newline(bytes)
16 | Event::ValueNotDone(bytes)
17 | Event::ValueDone(bytes)
18 | Event::Whitespace(bytes) => bytes.rebase(offset),
19 Event::KeyValueSeparator => Ok(()),
20 }
21 }
22
23 pub(crate) fn copy_to_backing_in(
24 &self,
25 source: &[u8],
26 target: &mut Vec<u8>,
27 ) -> Result<Event, crate::parse::span::Error> {
28 Ok(match self {
29 Event::Comment(comment) => Event::Comment(comment.copy_to_backing_in(source, target)?),
30 Event::SectionHeader(header) => Event::SectionHeader(header.copy_to_backing_in(source, target)?),
31 Event::SectionValueName(name) => Event::SectionValueName(name.copy_to_backing_in(source, target)?),
32 Event::Value(bytes) => Event::Value(bytes.copy_to_backing_in(source, target)?),
33 Event::Newline(bytes) => Event::Newline(bytes.copy_to_backing_in(source, target)?),
34 Event::ValueNotDone(bytes) => Event::ValueNotDone(bytes.copy_to_backing_in(source, target)?),
35 Event::ValueDone(bytes) => Event::ValueDone(bytes.copy_to_backing_in(source, target)?),
36 Event::Whitespace(bytes) => Event::Whitespace(bytes.copy_to_backing_in(source, target)?),
37 Event::KeyValueSeparator => Event::KeyValueSeparator,
38 })
39 }
40
41 pub(crate) fn as_ref_in<'a>(&'a self, backing: &'a [u8]) -> EventRef<'a> {
43 match self {
44 Event::Comment(comment) => EventRef::Comment {
45 tag: comment.tag,
46 text: comment.text.as_bstr_in(backing),
47 },
48 Event::SectionHeader(header) => EventRef::SectionHeader {
49 name: header.name.as_bstr_in(backing),
50 separator: header.separator.as_ref().map(|separator| separator.as_bstr_in(backing)),
51 subsection_name: header
52 .subsection_name
53 .as_ref()
54 .map(|subsection_name| subsection_name.value_in(backing)),
55 },
56 Event::SectionValueName(name) => EventRef::SectionValueName(name.as_bstr_in(backing)),
57 Event::Value(bytes) => EventRef::Value(bytes.as_bstr_in(backing)),
58 Event::Newline(bytes) => EventRef::Newline(bytes.as_bstr_in(backing)),
59 Event::ValueNotDone(bytes) => EventRef::ValueNotDone(bytes.as_bstr_in(backing)),
60 Event::ValueDone(bytes) => EventRef::ValueDone(bytes.as_bstr_in(backing)),
61 Event::Whitespace(bytes) => EventRef::Whitespace(bytes.as_bstr_in(backing)),
62 Event::KeyValueSeparator => EventRef::KeyValueSeparator,
63 }
64 }
65
66 pub(crate) fn to_bstr_lossy_in<'a>(&'a self, backing: &'a [u8]) -> &'a BStr {
73 match self {
74 Self::ValueNotDone(e) | Self::Whitespace(e) | Self::Newline(e) | Self::Value(e) | Self::ValueDone(e) => {
75 e.as_bstr_in(backing)
76 }
77 Self::KeyValueSeparator => "=".into(),
78 Self::SectionValueName(k) => k.as_bstr_in(backing),
79 Self::SectionHeader(h) => h.name.as_bstr_in(backing),
80 Self::Comment(c) => c.text.as_bstr_in(backing),
81 }
82 }
83
84 pub(crate) fn write_to_in(&self, backing: &[u8], out: &mut dyn std::io::Write) -> std::io::Result<()> {
85 match self {
86 Self::ValueNotDone(e) => {
87 out.write_all(e.as_slice_in(backing))?;
88 out.write_all(br"\")
89 }
90 Self::Whitespace(e) | Self::Newline(e) | Self::Value(e) | Self::ValueDone(e) => {
91 out.write_all(e.as_slice_in(backing))
92 }
93 Self::KeyValueSeparator => out.write_all(b"="),
94 Self::SectionValueName(k) => out.write_all(k.as_slice_in(backing)),
95 Self::SectionHeader(h) => h.write_to_in(backing, out),
96 Self::Comment(c) => c.write_to_in(backing, out),
97 }
98 }
99}
100
101impl EventRef<'_> {
102 pub fn to_bstr_lossy(&self) -> &BStr {
106 match self {
107 EventRef::ValueNotDone(bytes)
108 | EventRef::Whitespace(bytes)
109 | EventRef::Newline(bytes)
110 | EventRef::Value(bytes)
111 | EventRef::ValueDone(bytes) => bytes,
112 EventRef::KeyValueSeparator => "=".into(),
113 EventRef::SectionValueName(name) => name,
114 EventRef::SectionHeader { name, .. } => name,
115 EventRef::Comment { text, .. } => text,
116 }
117 }
118
119 pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
126 match self {
127 EventRef::ValueNotDone(bytes) => {
128 out.write_all(bytes)?;
129 out.write_all(br"\")
130 }
131 EventRef::Whitespace(bytes)
132 | EventRef::Newline(bytes)
133 | EventRef::Value(bytes)
134 | EventRef::ValueDone(bytes) => out.write_all(bytes),
135 EventRef::KeyValueSeparator => out.write_all(b"="),
136 EventRef::SectionValueName(name) => out.write_all(name),
137 EventRef::SectionHeader {
138 name,
139 separator,
140 subsection_name,
141 } => {
142 out.write_all(b"[")?;
143 out.write_all(name)?;
144 if let (Some(separator), Some(subsection_name)) = (separator, subsection_name) {
145 out.write_all(separator)?;
146 if *separator == b"." {
147 out.write_all(subsection_name)?;
148 } else {
149 out.write_all(b"\"")?;
150 crate::parse::section::header::write_escaped_subsection(subsection_name, &mut *out)?;
151 out.write_all(b"\"")?;
152 }
153 }
154 out.write_all(b"]")
155 }
156 EventRef::Comment { tag, text } => {
157 out.write_all(&[*tag])?;
158 out.write_all(text)
159 }
160 }
161 }
162}
163
164impl Display for EventRef<'_> {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 Display::fmt(&BString::from(self), f)
167 }
168}
169
170impl From<&EventRef<'_>> for BString {
171 fn from(event: &EventRef<'_>) -> Self {
172 let mut buf = Vec::new();
173 event.write_to(&mut buf).expect("io error impossible");
174 buf.into()
175 }
176}