use std::io; use std::io::BufRead; use regex::Regex; use crate::city::House; use crate::db::SqliteLayoutDB; mod city; mod db; enum State { Out, ReadPrice, In(usize), } fn main() { let mut db = SqliteLayoutDB::from_file("layouts.sqlite", false).expect("Failed to load the DB"); let stdin = io::stdin(); let price_regex = Regex::new("^Price ([0-9]*), seed ([0-9]*)$").unwrap(); let mut state = State::Out; let mut current_price = String::new(); let mut current_seed = String::new(); let mut houses = Vec::new(); for line in stdin.lock().lines() { let line = line.unwrap(); state = match state { State::Out => { if let Some(captures) = price_regex.captures(&line) { let price = captures.get(1).unwrap().as_str().to_string(); let seed = captures.get(2).unwrap().as_str().to_string(); // Ensure we only save the last layout for a seed if seed != current_seed && !houses.is_empty() { eprintln!("Saved house with seed {}, price {}", current_seed, current_price); db.add_layout(&houses, true); } else { houses.clear(); } current_seed = seed; current_price = price; State::ReadPrice } else { State::Out } }, State::ReadPrice => { let count: usize = line.parse().expect("Failed to read house count"); State::In(count) }, State::In(count) => { let mut parts = line.split_whitespace(); let y: usize = parts.next().unwrap().parse().expect("Failed to read y"); let x: usize = parts.next().unwrap().parse().expect("Failed to read x"); houses.push(House {x, y}); if count == 1 { State::Out } else { State::In(count - 1) } } } } if !houses.is_empty() { eprintln!("Saved house with seed {}, price {}", current_seed, current_price); db.add_layout(&houses, true); } }