pathfinder2/src/io.rs

112 lines
3.3 KiB
Rust
Raw Normal View History

2022-08-30 16:53:34 +00:00
use std::fs::File;
use std::io::Read;
2022-10-28 20:39:47 +00:00
use std::io::{self, BufRead};
use std::{collections::HashMap, io::BufReader};
2022-08-30 16:53:34 +00:00
2022-12-06 21:16:36 +00:00
use crate::types::edge::EdgeDB;
2022-08-30 21:30:38 +00:00
use crate::types::{Address, Edge, U256};
2022-08-30 16:53:34 +00:00
2022-12-06 21:16:36 +00:00
pub fn read_edges_binary(path: &String) -> Result<EdgeDB, io::Error> {
2022-08-30 16:53:34 +00:00
let mut f = File::open(path)?;
let address_index = read_address_index(&mut f)?;
read_edges(&mut f, &address_index)
}
2022-12-06 21:16:36 +00:00
pub fn read_edges_csv(path: &String) -> Result<EdgeDB, io::Error> {
let mut edges = Vec::new();
2022-10-28 20:39:47 +00:00
let f = BufReader::new(File::open(path)?);
for line in f.lines() {
let line = line?;
match &line.split(',').collect::<Vec<_>>()[..] {
[] => continue,
[from, to, token, capacity] => {
let from = Address::from(unescape(from));
let to = Address::from(unescape(to));
let token = Address::from(unescape(token));
let capacity = U256::from(unescape(capacity));
2022-12-06 21:16:36 +00:00
edges.push(Edge {
2022-10-28 20:39:47 +00:00
from,
to,
token,
capacity,
});
}
_ => {
return Result::Err(io::Error::new(
io::ErrorKind::Other,
format!("Expected from,to,token,capacity, but got {line}"),
))
}
}
}
2022-12-06 21:16:36 +00:00
Ok(EdgeDB::new(edges))
2022-10-28 20:39:47 +00:00
}
2022-08-30 16:53:34 +00:00
fn read_address_index(file: &mut File) -> Result<HashMap<u32, Address>, io::Error> {
let address_count = read_u32(file)?;
let mut addresses = HashMap::new();
for i in 0..address_count {
let mut buf = [0; 20];
file.read_exact(&mut buf)?;
addresses.insert(i, Address::from(buf));
}
Ok(addresses)
}
fn read_u32(file: &mut File) -> Result<u32, io::Error> {
let mut buf = [0; 4];
file.read_exact(&mut buf)?;
Ok(u32::from_be_bytes(buf))
}
fn read_u8(file: &mut File) -> Result<u8, io::Error> {
let mut buf = [0; 1];
file.read_exact(&mut buf)?;
Ok(u8::from_be_bytes(buf))
}
fn read_address(
file: &mut File,
address_index: &HashMap<u32, Address>,
) -> Result<Address, io::Error> {
let index = read_u32(file)?;
Ok(address_index[&index])
}
fn read_u256(file: &mut File) -> Result<U256, io::Error> {
let length = read_u8(file)? as usize;
let mut bytes = [0u8; 32];
file.read_exact(&mut bytes[32 - length..32])?;
let high = u128::from_be_bytes(*<&[u8; 16]>::try_from(&bytes[0..16]).unwrap());
2022-09-01 21:04:36 +00:00
let low = u128::from_be_bytes(*<&[u8; 16]>::try_from(&bytes[16..32]).unwrap());
2022-08-30 16:53:34 +00:00
Ok(U256::new(high, low))
}
2022-12-06 21:16:36 +00:00
fn read_edges(file: &mut File, address_index: &HashMap<u32, Address>) -> Result<EdgeDB, io::Error> {
2022-08-30 16:53:34 +00:00
let edge_count = read_u32(file)?;
2022-12-06 21:16:36 +00:00
let mut edges = Vec::new();
2022-08-30 16:53:34 +00:00
for _i in 0..edge_count {
let from = read_address(file, address_index)?;
let to = read_address(file, address_index)?;
let token = read_address(file, address_index)?;
let capacity = read_u256(file)?;
2022-12-06 21:16:36 +00:00
edges.push(Edge {
2022-08-30 16:53:34 +00:00
from,
to,
token,
capacity,
});
}
2022-12-06 21:16:36 +00:00
Ok(EdgeDB::new(edges))
2022-08-30 16:53:34 +00:00
}
2022-10-28 20:39:47 +00:00
fn unescape(input: &str) -> &str {
match input.chars().next() {
Some('"') | Some('\'') => {
assert!(input.len() >= 2 && input.chars().last() == input.chars().next());
&input[1..input.len() - 1]
}
_ => input,
}
}