Skip to content

Commit edcf33f

Browse files
committed
Make import functions return Result
1 parent c0ab571 commit edcf33f

File tree

5 files changed

+81
-55
lines changed

5 files changed

+81
-55
lines changed

benches/benchmarks.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn shortest_path_benchmark(c: &mut Criterion) {
2424
},
2525
);
2626

27-
let dimacs_g = load_tsplib_file("test_data/dimacs_tsp/d1291.tsp", usize::MAX);
27+
let dimacs_g = load_tsplib_file("test_data/dimacs_tsp/d1291.tsp", usize::MAX).unwrap();
2828
group.bench_with_input(
2929
BenchmarkId::new("DIMCAS d1291", &dimacs_g),
3030
&dimacs_g,
@@ -36,7 +36,7 @@ fn shortest_path_benchmark(c: &mut Criterion) {
3636
},
3737
);
3838

39-
let monaco_g = load_pbf_file("test_data/geofabrik/monaco-latest.osm.pbf");
39+
let monaco_g = load_pbf_file("test_data/geofabrik/monaco-latest.osm.pbf").unwrap();
4040
let mut monaco_cc = ConnectedComponents::new(&monaco_g);
4141
monaco_cc.run();
4242
let monaco_largest_g = monaco_cc.get_largest_connected_subgraphs();
@@ -73,14 +73,14 @@ fn shortest_path_benchmark(c: &mut Criterion) {
7373
fn travelling_salesman_benchmark(c: &mut Criterion) {
7474
let mut group = c.benchmark_group("Travelling salesman");
7575

76-
let dimacs_g = load_tsplib_file("test_data/dimacs_tsp/d1291.tsp", usize::MAX);
76+
let dimacs_g = load_tsplib_file("test_data/dimacs_tsp/d1291.tsp", usize::MAX).unwrap();
7777
group.bench_with_input(
7878
BenchmarkId::new("DIMCAS d1291", &dimacs_g),
7979
&dimacs_g,
8080
|b, g| b.iter(|| travelling_salesman(g, false)),
8181
);
8282

83-
let monaco_g = load_pbf_file("test_data/geofabrik/monaco-latest.osm.pbf");
83+
let monaco_g = load_pbf_file("test_data/geofabrik/monaco-latest.osm.pbf").unwrap();
8484

8585
let mut monaco_cc = ConnectedComponents::new(&monaco_g);
8686
monaco_cc.run();
@@ -102,7 +102,7 @@ fn travelling_salesman_benchmark(c: &mut Criterion) {
102102
}
103103

104104
fn connected_components_benchmark(c: &mut Criterion) {
105-
let g = load_pbf_file("test_data/geofabrik/monaco-latest.osm.pbf");
105+
let g = load_pbf_file("test_data/geofabrik/monaco-latest.osm.pbf").unwrap();
106106

107107
let mut group = c.benchmark_group("Connected components");
108108

src/graphs/algorithms/shortest_path.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::super::super::algorithms::PriorityQueue;
1+
use crate::algorithms::PriorityQueue;
22
use crate::graphs::datastructures::GraphPath;
33
use crate::graphs::datastructures::{Digraph, NodeIndex};
44

src/graphs/input/pbf.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,21 @@ use crate::graphs::datastructures::{ALDigraph, LatLng};
33
use crate::graphs::datastructures::{Digraph, NodeID};
44
use osmpbf::{Element, ElementReader};
55

6-
pub fn load_pbf_file(pbf_path: &str) -> ALDigraph {
7-
let reader = ElementReader::from_path(pbf_path).unwrap();
6+
#[derive(Debug)]
7+
pub enum PBFImportError {
8+
OSMPBFError(osmpbf::Error),
9+
}
10+
11+
impl From<osmpbf::Error> for PBFImportError {
12+
fn from(err: osmpbf::Error) -> PBFImportError {
13+
PBFImportError::OSMPBFError(err)
14+
}
15+
}
16+
17+
type Result<T> = std::result::Result<T, PBFImportError>;
18+
19+
pub fn load_pbf_file(pbf_path: &str) -> Result<ALDigraph> {
20+
let reader = ElementReader::from_path(pbf_path)?;
821

922
let num_nodes = reader
1023
.par_map_reduce(
@@ -15,16 +28,15 @@ pub fn load_pbf_file(pbf_path: &str) -> ALDigraph {
1528
},
1629
|| 0_u64, // Zero is the identity value for addition
1730
|a, b| a + b, // Sum the partial results
18-
)
19-
.unwrap();
31+
)?;
2032

2133
println!("Number of nodes: {num_nodes}");
2234

2335
let mut g = ALDigraph::new(num_nodes as usize);
2436

2537
println!("Graph initialised");
2638

27-
let reader = ElementReader::from_path(pbf_path).unwrap();
39+
let reader = ElementReader::from_path(pbf_path)?;
2840

2941
reader
3042
.for_each(|element| {
@@ -45,14 +57,13 @@ pub fn load_pbf_file(pbf_path: &str) -> ALDigraph {
4557
},
4658
)
4759
}
48-
})
49-
.unwrap();
60+
})?;
5061

5162
println!("Nodes added");
5263

5364
let mut ways = 0_u64;
5465

55-
let reader = ElementReader::from_path(pbf_path).unwrap();
66+
let reader = ElementReader::from_path(pbf_path)?;
5667

5768
reader
5869
.for_each(|element| {
@@ -74,10 +85,9 @@ pub fn load_pbf_file(pbf_path: &str) -> ALDigraph {
7485
}
7586
ways += 1;
7687
}
77-
})
78-
.unwrap();
88+
})?;
7989

8090
println!("Edges added");
8191

82-
g
92+
Ok(g)
8393
}

src/graphs/input/tsplib.rs

+44-30
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,30 @@ use rand::{thread_rng, Rng};
33
use std::{cmp, fs, io::Cursor};
44
use tsplib::NodeCoord;
55

6-
pub fn generate_random_tsplib_file(num_nodes: usize) -> String {
7-
let mut rng = thread_rng();
8-
9-
let mut lines: Vec<String> = Vec::with_capacity(num_nodes);
10-
11-
lines.push("NAME : example".to_string());
12-
lines.push("TYPE : TSP".to_string());
13-
lines.push(format!("DIMENSION : {}", num_nodes + 1));
14-
lines.push("EDGE_WEIGHT_TYPE: EUC_2D".to_string());
15-
lines.push("NODE_COORD_SECTION".to_string());
6+
#[derive(Debug)]
7+
pub enum TSPLIBImportError {
8+
IOError(std::io::Error),
9+
OtherError(String),
10+
}
1611

17-
let grid_size = num_nodes * 10;
18-
for i in 0..num_nodes {
19-
lines.push(format!(
20-
"{} {} {}",
21-
i,
22-
rng.gen::<f32>() * (grid_size as f32),
23-
rng.gen::<f32>() * (grid_size as f32)
24-
))
12+
impl From<std::io::Error> for TSPLIBImportError {
13+
fn from(err: std::io::Error) -> TSPLIBImportError {
14+
TSPLIBImportError::IOError(err)
2515
}
26-
27-
lines.push("EOF".to_string());
28-
29-
lines.join("\n")
3016
}
3117

32-
pub fn load_tsplib_file(file_path: &str, num_nodes: usize) -> AMDigraph {
33-
let tsp_string = fs::read_to_string(file_path).unwrap();
34-
let instance = tsplib::parse(Cursor::new(&tsp_string[..])).unwrap();
18+
type Result<T> = std::result::Result<T, TSPLIBImportError>;
19+
20+
pub fn load_tsplib_file(file_path: &str, num_nodes: usize) -> Result<AMDigraph> {
21+
let tsp_string = fs::read_to_string(file_path)?;
22+
let instance = tsplib::parse(Cursor::new(&tsp_string[..]))?;
3523

3624
let actual_num_nodes = cmp::min(num_nodes, instance.dimension);
3725

38-
let coords = match instance.node_coord.unwrap() {
39-
NodeCoord::Two(x) => x,
40-
_ => panic!("Wrong format"),
41-
};
26+
let coords = match instance.node_coord.ok_or(TSPLIBImportError::OtherError("No node coords found".to_string()))? {
27+
NodeCoord::Two(x) => Ok(x),
28+
_ => Err(TSPLIBImportError::OtherError("No node coords found".to_string())),
29+
}?;
4230

4331
let mut g = AMDigraph::new(actual_num_nodes);
4432

@@ -64,5 +52,31 @@ pub fn load_tsplib_file(file_path: &str, num_nodes: usize) -> AMDigraph {
6452
}
6553
}
6654

67-
g
55+
Ok(g)
56+
}
57+
58+
pub fn generate_random_tsplib_file(num_nodes: usize) -> String {
59+
let mut rng = thread_rng();
60+
61+
let mut lines: Vec<String> = Vec::with_capacity(num_nodes);
62+
63+
lines.push("NAME : example".to_string());
64+
lines.push("TYPE : TSP".to_string());
65+
lines.push(format!("DIMENSION : {}", num_nodes + 1));
66+
lines.push("EDGE_WEIGHT_TYPE: EUC_2D".to_string());
67+
lines.push("NODE_COORD_SECTION".to_string());
68+
69+
let grid_size = num_nodes * 10;
70+
for i in 0..num_nodes {
71+
lines.push(format!(
72+
"{} {} {}",
73+
i,
74+
rng.gen::<f32>() * (grid_size as f32),
75+
rng.gen::<f32>() * (grid_size as f32)
76+
))
77+
}
78+
79+
lines.push("EOF".to_string());
80+
81+
lines.join("\n")
6882
}

src/main.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
#[macro_use]
22
extern crate rocket;
33

4+
use std::ops::Deref;
5+
use std::sync::{Arc, RwLock};
6+
7+
use rocket::fairing::{Fairing, Info, Kind};
8+
use rocket::http::Header;
9+
use rocket::serde::{Deserialize, Serialize};
10+
use rocket::serde::json::Json;
11+
412
use broute::graphs::algorithms::{
5-
form_abstracted_graph, travelling_salesman, ConnectedComponents, Dijkstra,
13+
ConnectedComponents, Dijkstra, form_abstracted_graph, travelling_salesman,
614
};
715
use broute::graphs::datastructures::{ALDigraph, Digraph, LatLng, NodeID};
816
use broute::graphs::input::load_pbf_file;
9-
use rocket::fairing::{Fairing, Info, Kind};
10-
use rocket::http::Header;
11-
use rocket::serde::json::Json;
12-
use rocket::serde::{Deserialize, Serialize};
13-
use std::ops::Deref;
14-
use std::sync::{Arc, RwLock};
1517

1618
#[cfg(test)]
1719
mod tests;
@@ -170,7 +172,7 @@ impl Fairing for CORS {
170172
}
171173

172174
async fn get_graph() -> ALDigraph {
173-
let g = load_pbf_file("test_data/geofabrik/monaco-latest.osm.pbf");
175+
let g = load_pbf_file("test_data/geofabrik/monaco-latest.osm.pbf").unwrap();
174176

175177
println!("Original graph {:} nodes", g.num_vertices());
176178

0 commit comments

Comments
 (0)