]> git.proxmox.com Git - rustc.git/blame - vendor/gix-config/src/file/impls.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / vendor / gix-config / src / file / impls.rs
CommitLineData
0a29b90c
FG
1use std::{borrow::Cow, convert::TryFrom, fmt::Display, str::FromStr};
2
3use bstr::{BStr, BString, ByteVec};
4
5use crate::{
6 file::Metadata,
7 parse,
8 parse::{section, Event},
9 value::normalize,
10 File,
11};
12
13impl FromStr for File<'static> {
14 type Err = parse::Error;
15
16 fn from_str(s: &str) -> Result<Self, Self::Err> {
17 parse::Events::from_bytes_owned(s.as_bytes(), None)
18 .map(|events| File::from_parse_events_no_includes(events, Metadata::api()))
19 }
20}
21
22impl<'a> TryFrom<&'a str> for File<'a> {
23 type Error = parse::Error;
24
25 /// Convenience constructor. Attempts to parse the provided string into a
26 /// [`File`]. See [`Events::from_str()`][crate::parse::Events::from_str()] for more information.
27 fn try_from(s: &'a str) -> Result<File<'a>, Self::Error> {
28 parse::Events::from_str(s).map(|events| Self::from_parse_events_no_includes(events, Metadata::api()))
29 }
30}
31
32impl<'a> TryFrom<&'a BStr> for File<'a> {
33 type Error = parse::Error;
34
35 /// Convenience constructor. Attempts to parse the provided byte string into
36 /// a [`File`]. See [`Events::from_bytes()`][parse::Events::from_bytes()] for more information.
37 fn try_from(value: &'a BStr) -> Result<File<'a>, Self::Error> {
38 parse::Events::from_bytes(value, None)
39 .map(|events| Self::from_parse_events_no_includes(events, Metadata::api()))
40 }
41}
42
43impl From<File<'_>> for BString {
44 fn from(c: File<'_>) -> Self {
45 c.into()
46 }
47}
48
49impl Display for File<'_> {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 Display::fmt(&self.to_bstring(), f)
52 }
53}
54
55impl PartialEq for File<'_> {
56 fn eq(&self, other: &Self) -> bool {
57 fn find_key<'a>(mut it: impl Iterator<Item = &'a Event<'a>>) -> Option<&'a section::Key<'a>> {
58 it.find_map(|e| match e {
59 Event::SectionKey(k) => Some(k),
60 _ => None,
61 })
62 }
63 fn collect_value<'a>(it: impl Iterator<Item = &'a Event<'a>>) -> Cow<'a, BStr> {
64 let mut partial_value = BString::default();
65 let mut value = None;
66
67 for event in it {
68 match event {
69 Event::SectionKey(_) => break,
70 Event::Value(v) => {
71 value = v.clone().into();
72 break;
73 }
74 Event::ValueNotDone(v) => partial_value.push_str(v.as_ref()),
75 Event::ValueDone(v) => {
76 partial_value.push_str(v.as_ref());
77 value = Some(partial_value.into());
78 break;
79 }
80 _ => (),
81 }
82 }
83 value.map(normalize).unwrap_or_default()
84 }
85 if self.section_order.len() != other.section_order.len() {
86 return false;
87 }
88
89 for (lhs, rhs) in self
90 .section_order
91 .iter()
92 .zip(&other.section_order)
93 .map(|(lhs, rhs)| (&self.sections[lhs], &other.sections[rhs]))
94 {
95 if !(lhs.header.name == rhs.header.name && lhs.header.subsection_name == rhs.header.subsection_name) {
96 return false;
97 }
98
99 let (mut lhs, mut rhs) = (lhs.body.0.iter(), rhs.body.0.iter());
100 while let (Some(lhs_key), Some(rhs_key)) = (find_key(&mut lhs), find_key(&mut rhs)) {
101 if lhs_key != rhs_key {
102 return false;
103 }
104 if collect_value(&mut lhs) != collect_value(&mut rhs) {
105 return false;
106 }
107 }
108 }
109 true
110 }
111}