gdritter repos rrecutils / f989c68
Switched .get to Result instead of Option Getty Ritter 6 years ago
1 changed file(s) with 42 addition(s) and 7 deletion(s). Collapse all Expand all
1010 }
1111
1212
13 /// A `Record` is a single bundle of key-value pairs with a few pieces
14 /// of optional metadata. This preserves the order of the values
15 /// contained.
1316 #[derive(Eq, PartialEq, Debug)]
1417 pub struct Record {
1518 pub rec_type: Option<String>,
1720 }
1821
1922 impl Record {
23 /// Write the serialized version of this `Record` to the provided `Write`r
2024 pub fn write<W>(&self, w: &mut W) -> std::io::Result<()>
2125 where W: std::io::Write
2226 {
2731 write!(w, "\n")
2832 }
2933
34 /// Turn this `Record` into a serialized string representation
35 pub fn to_string(&self) -> std::io::Result<String> {
36 let mut s = std::io::Cursor::new(Vec::new());
37 self.write(&mut s)?;
38 // XXX: this SHOULD be fine, but make sure!
39 Ok(String::from_utf8(s.into_inner()).unwrap())
40 }
41
42 /// Return the number of fields in this record
3043 pub fn size(&self) -> usize {
3144 self.fields.len()
3245 }
3346
34 pub fn get<'a>(&'a self, name: &str) -> Option<&'a str> {
47 /// Return the value of the field named by the argument if it
48 /// exists
49 pub fn get<'a>(&'a self, name: &str) -> Result<&'a str, RecError> {
3550 self.fields.iter()
3651 .find(|&&(ref p, _)| p == name)
3752 .map(|&(_, ref q)| q.as_ref())
38 }
39 }
40
41
53 .ok_or(RecError::MissingField { name: name.to_owned() })
54 }
55 }
56
57
58 /// A `Recfile` is a sequence of `Record`.
4259 #[derive(Eq, PartialEq, Debug)]
4360 pub struct Recfile {
4461 pub records: Vec<Record>,
4562 }
4663
4764 impl Recfile {
65 /// Serialize this `Recfile` to the provided `Write`r
4866 pub fn write<W>(&self, w: &mut W) -> std::io::Result<()>
4967 where W: std::io::Write
5068 {
5573 Ok(())
5674 }
5775
76 /// Turn this `Recfile` into a serialized string representation
77 pub fn to_string(&self) -> std::io::Result<String> {
78 let mut s = std::io::Cursor::new(Vec::new());
79 self.write(&mut s)?;
80 // XXX: this SHOULD be fine, but make sure!
81 Ok(String::from_utf8(s.into_inner()).unwrap())
82 }
83
84 /// Modify this Recfile in-place by only keeping the records of a
85 /// particular type
5886 pub fn filter_by_type(&mut self, type_name: &str) {
5987 self.records.retain(|r| match r.rec_type {
6088 Some(ref t) => t == type_name,
6290 });
6391 }
6492
93 /// Iterate over a subset of the records in this recfile
6594 pub fn iter_by_type<'a>(&'a self, type_name: &'a str) -> RecIterator<'a> {
6695 RecIterator {
6796 typ: type_name,
6998 }
7099 }
71100
101 /// Iterate over _all_ the records in this recfile
72102 pub fn iter<'a>(&'a self) -> std::slice::Iter<'a, Record> {
73103 self.records.iter()
74104 }
75105 }
76106
77107 pub struct RecIterator<'a> {
78 pub typ: &'a str,
79 pub rec: std::slice::Iter<'a, Record>,
108 typ: &'a str,
109 rec: std::slice::Iter<'a, Record>,
80110 }
81111
82112 impl<'a> Iterator for RecIterator<'a> {
108138 #[fail(display = "Invalid line: {}", ln)]
109139 InvalidLine {
110140 ln: String,
141 },
142
143 #[fail(display = "Missing key: {}", name)]
144 MissingField {
145 name: String,
111146 },
112147 }
113148