use std::io::Error;
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
use serde_json::Value;
use tokio::{
fs::File,
io::{AsyncWriteExt, AsyncReadExt},
runtime::Builder,
};
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "type")]
pub enum Element {
Node {
id: u64,
lat: f64,
lon: f64,
tags: Option<HashMap<String, String>>
},
Way {
id: u64,
nodes: Vec<u64>,
tags: Option<Value>,
}
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub struct OverpassResponse {
elements: Vec<Element>,
generator: Value,
osm3s: Value,
version: Value
}
impl OverpassResponse {
pub fn elements(&self) -> &Vec<Element> {
&self.elements
}
pub fn generator(&self) -> &Value {
&self.generator
}
pub fn osm3s(&self) -> &Value {
&self.osm3s
}
pub fn version(&self) -> &Value {
&self.version
}
pub async fn save(&self, filepath: &str) -> Result<(), Error> {
let list_as_json = serde_json::to_string(self)?;
let mut file = File::create(filepath).await?;
file.write_all(list_as_json.as_bytes()).await?;
file.flush().await?;
Ok(())
}
pub fn save_blocking(&self, filepath: &str) -> Result<(), Error> {
Builder::new_current_thread()
.enable_all()
.build()?
.block_on(self.save(filepath))
}
pub async fn load(filepath: &str) -> Result<Self, Error> {
let mut file = File::open(filepath).await?;
let mut contents = Vec::new();
file.read_to_end(&mut contents).await?;
let contents_as_string: String = String::from_utf8_lossy(&contents).to_string();
let json: OverpassResponse = serde_json::from_str(&contents_as_string)?;
Ok(json)
}
pub fn load_blocking(filepath: &str) -> Result<Self, Error> {
Builder::new_current_thread()
.enable_all()
.build()?
.block_on(Self::load(filepath))
}
}