1
1
use crate :: { borrowed, spanned, Span } ;
2
2
use bstr:: { BStr , ByteSlice } ;
3
3
4
+ #[ derive( Clone , PartialOrd , PartialEq , Ord , Eq ) ]
4
5
pub ( crate ) enum Token {
5
6
Section ( spanned:: Section ) ,
6
7
Entry ( spanned:: Entry ) ,
@@ -23,13 +24,18 @@ impl Token {
23
24
}
24
25
25
26
/// The entry point into reading and writing git config files.
27
+ ///
28
+ /// After reading a configuration file its contents is stored verbatim and indexed to allow retrieval
29
+ /// of sections and entry values on demand. These are returned as [`borrowed`] items, which are read-only but
30
+ /// can be transformed into editable items.
31
+ #[ derive( Clone , PartialOrd , PartialEq , Ord , Eq ) ]
26
32
pub struct File {
27
33
buf : Vec < u8 > ,
28
34
/// A config file as parsed into tokens, where each [`Token`] is one of the three relevant items in git config files.
29
35
tokens : Vec < Token > , // but how do we get fast lookups and proper value lookup based on decoded values?
30
36
// On the fly is easier, otherwise we have to deal with a lookup cache of sorts and
31
- // many more allocations up front (which might be worth it). Cow<'a, _> would bind to
32
- // our buffer so the cache can't be in this type.
37
+ // many more allocations up front (which might be worth it only once we have measurements).
38
+ // Cow<'a, _> would bind to our buffer so the cache can't be in this type.
33
39
// Probably it could be the 'Config' type which handles multiple files and treats them as one,
34
40
// and only if there is any need.
35
41
}
@@ -45,6 +51,9 @@ impl File {
45
51
}
46
52
47
53
impl File {
54
+ /// Returns an iterator over all sections and sub-sections of the configuration file.
55
+ ///
56
+ /// Note that every entry must be part of a section, that is global entries/key-value pairs are not allowed.
48
57
pub fn sections ( & self ) -> impl Iterator < Item = borrowed:: Section < ' _ > > {
49
58
self . tokens
50
59
. iter ( )
@@ -54,6 +63,7 @@ impl File {
54
63
}
55
64
56
65
impl < ' a > borrowed:: Section < ' a > {
66
+ /// Returns an iterator over all entries in a section.
57
67
pub fn entries ( & self ) -> impl Iterator < Item = borrowed:: Entry < ' _ > > {
58
68
struct Iter < ' a > {
59
69
inner : Option < & ' a [ Token ] > ,
@@ -97,72 +107,5 @@ impl<'a> borrowed::Section<'a> {
97
107
}
98
108
}
99
109
100
- mod edit {
101
- use crate :: { borrowed, file:: File , owned, Span } ;
102
- use std:: io;
103
-
104
- impl Into < Edit > for owned:: Section {
105
- fn into ( self ) -> Edit {
106
- Edit :: SetSection ( self )
107
- }
108
- }
109
-
110
- impl Into < Edit > for owned:: Entry {
111
- fn into ( self ) -> Edit {
112
- Edit :: SetEntry ( self )
113
- }
114
- }
115
-
116
- enum Edit {
117
- Delete ( Span ) , // section or entry
118
- SetSection ( owned:: Section ) ,
119
- SetEntry ( owned:: Entry ) ,
120
- }
121
-
122
- /// Collects edits to be applied to a [`File`], to be written out eventually.
123
- pub struct Edits < ' a > {
124
- parent : & ' a File ,
125
- edits : Vec < Edit > ,
126
- }
127
-
128
- impl < ' a > Edits < ' a > {
129
- pub fn delete_section ( & mut self , section : & borrowed:: Section < ' _ > ) -> & mut Self {
130
- self . edits . push ( Edit :: Delete (
131
- self . parent . token ( section. index ) . as_section ( ) . expect ( "section" ) . name ,
132
- ) ) ;
133
- self
134
- }
135
- pub fn delete_entry ( & mut self , entry : & borrowed:: Entry < ' _ > ) -> & mut Self {
136
- self . edits . push ( Edit :: Delete (
137
- self . parent . token ( entry. index ) . as_entry ( ) . expect ( "entry" ) . name ,
138
- ) ) ;
139
- self
140
- }
141
- // Use with [`owned::Section`].
142
- //
143
- // Newly [instantiated][owned::Section::new()] sections will be appended, and existing ones can be edited
144
- // by calling [`borrowed::Section::to_editable()`].
145
- pub fn create_or_update_section ( & mut self , section : owned:: Section ) -> & mut Self {
146
- self . edits . push ( Edit :: SetSection ( section) ) ;
147
- self
148
- }
149
- pub fn create_or_update_entry ( & mut self , entry : owned:: Entry ) -> & mut Self {
150
- self . edits . push ( Edit :: SetEntry ( entry) ) ;
151
- self
152
- }
153
-
154
- pub fn to_write ( & self , _out : impl io:: Write ) -> io:: Result < ( ) > {
155
- unimplemented ! ( "to write" )
156
- }
157
- }
158
-
159
- impl File {
160
- pub fn edit ( & self ) -> Edits {
161
- Edits {
162
- parent : self ,
163
- edits : Vec :: new ( ) ,
164
- }
165
- }
166
- }
167
- }
110
+ mod edit;
168
111
pub use edit:: Edits ;
0 commit comments