93 lines
3.5 KiB
Rust
93 lines
3.5 KiB
Rust
extern crate pest;
|
|
|
|
use crate::Value::{QmlIdent, QmlNumber, QmlString};
|
|
use pest::iterators::Pairs;
|
|
use pest::Parser;
|
|
use std::collections::HashMap;
|
|
use std::fs::read_to_string;
|
|
|
|
#[derive(Parser)]
|
|
#[grammar = "../pest/qml.pest"]
|
|
struct QmlParser;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum Value {
|
|
QmlString(String),
|
|
QmlNumber(f64),
|
|
QmlIdent(String),
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct QML {
|
|
pub imports: Vec<String>,
|
|
pub properties: HashMap<String, Value>,
|
|
pub children: Vec<(String, QML)>,
|
|
}
|
|
|
|
pub fn parse_qml(path: &str) -> QML {
|
|
let qml_file = read_to_string(path).unwrap();
|
|
let qml_tokens = QmlParser::parse(Rule::qml, qml_file.as_str()).unwrap_or_else(|e| panic!("{}", e));
|
|
parse(qml_tokens)
|
|
}
|
|
|
|
fn parse(qml: Pairs<Rule>) -> QML {
|
|
let mut qmldoc = QML {
|
|
imports: vec![],
|
|
properties: Default::default(),
|
|
children: vec![],
|
|
};
|
|
for pair in qml {
|
|
// println!("Rule {:?} Str {}", pair.as_rule(), pair.as_str());
|
|
|
|
match pair.as_rule() {
|
|
Rule::import => {
|
|
let mut tokens = pair.into_inner();
|
|
let import = tokens.next().unwrap().as_str();
|
|
println!("Found new Import {} ", import);
|
|
qmldoc.imports.push(String::from(import));
|
|
}
|
|
Rule::body => {
|
|
let mut tokens = pair.into_inner();
|
|
let ident = tokens.next().unwrap().as_str();
|
|
println!("Found new Body: {} ", ident);
|
|
qmldoc.children.push((String::from(ident), parse(tokens.into_iter())));
|
|
}
|
|
Rule::property => {
|
|
let mut tokens = pair.into_inner();
|
|
let ident = tokens.next().unwrap().as_str();
|
|
let value = tokens.next().unwrap();
|
|
// let value = tokens.next().unwrap().as_str();
|
|
match value.as_rule() {
|
|
Rule::number => {
|
|
let num: f64 = value.as_str().parse().unwrap();
|
|
println!("Found new Property: {} {:?}", ident, num);
|
|
qmldoc.properties.insert(String::from(ident), QmlNumber(num));
|
|
}
|
|
Rule::string => {
|
|
println!("Found new Property: {} {}", ident, value.as_str());
|
|
qmldoc.properties.insert(String::from(ident), QmlString(String::from(value.into_inner().next().unwrap().as_str())));
|
|
}
|
|
Rule::ident => {
|
|
println!("Found new Property: {} {}", ident, value.as_str());
|
|
qmldoc.properties.insert(String::from(ident), QmlIdent(String::from(value.as_str())));
|
|
}
|
|
_ => {
|
|
println!("Found new Property: {} {:?}", ident, value.as_rule());
|
|
let value = String::from(value.as_str()) + tokens.concat().as_ref();
|
|
println!("Found new Property: {} {}", ident, value.as_str());
|
|
qmldoc.properties.insert(String::from(ident), QmlString(String::from(value.clone().trim())));
|
|
}
|
|
}
|
|
}
|
|
Rule::function => {
|
|
let mut tokens = pair.into_inner();
|
|
let ident = tokens.next().unwrap().as_str();
|
|
let value = tokens.concat();
|
|
qmldoc.properties.insert(String::from(ident), QmlString(String::from(value.clone().trim())));
|
|
}
|
|
_ => return parse(pair.into_inner()),
|
|
}
|
|
}
|
|
qmldoc
|
|
}
|