123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- use std::collections::HashMap;
- #[derive(serde::Deserialize)]
- struct Margin {
- top: isize,
- bottom: isize,
- left: isize,
- right: isize,
- }
- #[derive(serde::Deserialize)]
- struct Node {
- id: usize,
- behaviour: String,
- child_arrangement: String,
- width_policy: [usize; 3],
- height_policy: [usize; 3],
- halign: String,
- valign: String,
- margin: Margin,
- table_cell: Option<[usize; 2]>,
- render_area: Option<[[usize; 2]; 2]>,
- children: Vec<Node>,
- }
- fn main() {
- let mut args = std::env::args();
- let execname = args.next().unwrap();
- if args.len() != 1 {
- println!("usage: {} path-to-json", execname);
- return;
- }
- let fname = args.next().unwrap();
- let indata = std::fs::read(fname).expect("couldn't open file");
- let nodetree: Node = serde_json::from_slice(&indata).expect("couldn't parse file");
- let mut x_pos: HashMap<usize, usize> = HashMap::new();
- let mut y_pos: HashMap<usize, usize> = HashMap::new();
- let mut parents: HashMap<usize, usize> = HashMap::new();
- let mut siblings: HashMap<usize, usize> = HashMap::new();
- let mut dfs = vec![&nodetree];
- let mut max_x = 0;
- while let Some(node) = dfs.pop() {
- println!("visiting node {}", node.id);
- // X coordinate:
- // case 1: no sibling, so same x as parent
- // case 2: sibling, so use max_x + 1
- // Y coordinate:
- // always use parent's y pos + 1
- let x = match siblings.get(&node.id) {
- None => parents
- .get(&node.id)
- .and_then(|p| x_pos.get(p))
- .cloned()
- .unwrap_or(0),
- Some(_sib) => max_x + 1,
- };
- let y = parents
- .get(&node.id)
- .and_then(|p| y_pos.get(p))
- .map(|v| v + 1)
- .unwrap_or(0);
- max_x = max_x.max(x);
- x_pos.insert(node.id, x);
- y_pos.insert(node.id, y);
- let mut sibling: Option<usize> = None;
- for ch in node.children.iter() {
- parents.insert(ch.id, node.id);
- if let Some(sibling) = sibling {
- siblings.insert(ch.id, sibling);
- }
- sibling = Some(ch.id);
- dfs.push(ch);
- }
- }
- let mut yvalues = y_pos.values().collect::<Vec<_>>();
- yvalues.sort();
- yvalues.dedup();
- for y in yvalues {
- let mut line = y_pos
- .iter()
- .filter(|(_, v)| *v == y)
- .map(|(k, _)| (x_pos.get(k).unwrap(), k))
- .collect::<Vec<_>>();
- line.sort();
- println!("{line:?}");
- }
- }
|