snark_tool/service/io/
reader_ba.rs1use std::fs::File;
2use std::io::{self, BufRead};
3
4use crate::graph::graph::{Graph, GraphConstructor};
5use crate::service::io::error::ReadError;
6use crate::service::io::reader::GraphFileReader;
7use std::{fs, marker, result};
8
9type Result<T> = result::Result<T, ReadError>;
10
11const WRONG_FORMAT: &str = "Wrong ba format";
12
13pub struct BaReader<'a, G> {
14 lines: io::Lines<io::BufReader<&'a fs::File>>,
15 graphs_count: Option<usize>,
16 _ph: marker::PhantomData<G>,
17}
18
19impl<'a, G> GraphFileReader<'a, G> for BaReader<'a, G>
20where
21 G: Graph + GraphConstructor,
22{
23 fn new(file: &'a File) -> Self {
24 BaReader {
25 lines: io::BufReader::new(file).lines(),
26 graphs_count: None,
28 _ph: marker::PhantomData,
29 }
30 }
31
32 fn next(&mut self) -> Option<Result<G>> {
33 if self.graphs_count.is_none() {
34 let count = self.get_graphs_count();
35 match count {
36 Ok(count_) => {
37 self.graphs_count = Some(count_);
38 }
39 Err(error) => {
40 return Some(Err(error));
41 }
42 }
43 }
44 let graph = self.read_graph_ba();
45 graph.transpose()
46 }
47}
48
49impl<'a, G> BaReader<'a, G>
50where
51 G: Graph + GraphConstructor,
52{
53 fn get_graphs_count(&mut self) -> Result<usize> {
54 let graphs_count = self.next_numbers_vector()?;
55 let count = graphs_count.get(0);
56 if count.is_some() {
57 return Ok(count.unwrap().clone());
58 }
59 Err(ReadError {
60 message: "Wrong ba format - graphs count missing".to_string(),
61 })
62 }
63
64 fn next_numbers_vector(&mut self) -> Result<Vec<usize>> {
65 let mut vector = Vec::<usize>::new();
66 let mut line = self.lines.next();
67
68 while line.is_some() {
69 if let Ok(line_str) = line.unwrap() {
70 if line_str.trim().chars().next().unwrap() == '{' {
71 line = self.lines.next();
72 continue;
73 }
74 let mut split = line_str.split_whitespace();
75 let mut next = split.next();
76 while next.is_some() {
77 vector.push(next.unwrap().parse()?);
78 next = split.next();
79 }
80 if !vector.is_empty() {
81 return Ok(vector);
82 }
83 }
84 line = self.lines.next();
85 }
86 Ok(vector)
87 }
88
89 fn get_serial_number(&mut self) -> Result<Option<usize>> {
90 self.get_single_number()
91 }
92
93 fn get_size(&mut self) -> Result<usize> {
94 let result = self.get_single_number();
95 return match result {
96 Ok(opt) => {
97 if opt.is_some() {
98 return Ok(opt.unwrap());
99 }
100 Err(ReadError {
101 message: format!("{}: size not found", WRONG_FORMAT),
102 })
103 }
104 Err(err) => Err(err),
105 };
106 }
107
108 fn get_single_number(&mut self) -> Result<Option<usize>> {
109 let mut vec = self.next_numbers_vector()?;
110 if vec.len() == 1 {
111 return Ok(vec.pop());
112 }
113 if vec.is_empty() {
114 return Ok(None);
115 }
116 Err(ReadError {
117 message: "asked for single number but get vector".to_string(),
118 })
119 }
120
121 fn read_graph_ba(&mut self) -> Result<Option<G>> {
122 let serial_number = self.get_serial_number()?;
123 if serial_number.is_none() {
124 return Ok(None);
125 }
126 let size = self.get_size()?;
127 let edges = (size * 3 / 2) as usize;
128 let mut graph = G::with_capacity(size, edges);
129 for from in 0..size {
130 let vec = self.next_numbers_vector()?;
131 for to in vec.iter() {
132 graph.add_edge(from, to.clone());
133 }
134 }
135 Ok(Some(graph))
136 }
137}
138
139pub fn read_preface_and_count(file: &File) -> Result<(usize, String)> {
140 let mut lines = io::BufReader::new(file).lines();
141 let mut comments = String::new();
142 let mut line = lines.next();
143 while line.is_some() {
144 if let Ok(mut line_str) = line.unwrap() {
145 let first_char = line_str.trim().chars().next();
146 if first_char.is_some() && first_char.unwrap() != '{' {
147 line_str = String::from(line_str.trim());
148 let count = line_str.parse()?;
149 return Ok((count, comments));
150 }
151 comments.push_str(line_str.as_ref());
152 comments.push_str("\n");
153 line = lines.next();
154 } else {
155 return Err(ReadError {
156 message: format!("unknown read error"),
157 });
158 }
159 }
160 Ok((0, comments))
161}