From b28ce15b16a852e89886a798dd53352cc8611f65 Mon Sep 17 00:00:00 2001 From: veradec Date: Fri, 11 Sep 2026 21:14:20 +0530 Subject: fix: restructure package into library --- Cargo.lock | 294 ------------------------------------------------------------ Cargo.toml | 6 +- src/lib.rs | 234 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 236 +----------------------------------------------- 4 files changed, 239 insertions(+), 531 deletions(-) create mode 100644 src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d9dedbe..bd5745f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,170 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "anstream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" - -[[package]] -name = "anstyle-parse" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "colorchoice" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" - -[[package]] -name = "defmt" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" -dependencies = [ - "bitflags", - "defmt-macros", -] - -[[package]] -name = "defmt-macros" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" -dependencies = [ - "defmt-parser", - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "defmt-parser" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" -dependencies = [ - "thiserror", -] - -[[package]] -name = "env_filter" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", - "log", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - -[[package]] -name = "jiff" -version = "0.2.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" -dependencies = [ - "defmt", - "jiff-core", - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde_core", -] - -[[package]] -name = "jiff-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" -dependencies = [ - "defmt", -] - -[[package]] -name = "jiff-static" -version = "0.2.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" -dependencies = [ - "jiff-core", - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "log" -version = "0.4.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" - [[package]] name = "memchr" version = "2.8.3" @@ -185,50 +21,9 @@ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" name = "okaml" version = "0.1.0" dependencies = [ - "env_logger", - "log", "regex", ] -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - -[[package]] -name = "portable-atomic" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" - -[[package]] -name = "portable-atomic-util" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "proc-macro2" -version = "1.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" -dependencies = [ - "proc-macro2", -] - [[package]] name = "regex" version = "1.13.1" @@ -257,92 +52,3 @@ name = "regex-syntax" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" - -[[package]] -name = "serde_core" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.5", -] - -[[package]] -name = "syn" -version = "2.0.119" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "3.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "2.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.5", -] - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] diff --git a/Cargo.toml b/Cargo.toml index 0c0422f..28bd5ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,9 @@ authors = ["Venkata Rao Dechiraju", "verade@duck.com"] version = "0.1.0" edition = "2024" +[lib] +name = "okaml" +path = "src/lib.rs" + [dependencies] -env_logger = "0.11.11" -log = "0.4.34" regex = "1.13.1" diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..5104167 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,234 @@ +#![allow(unused)] +use std::fs; +use regex::Regex; + +#[derive(Debug)] +pub enum OkmlType { + String(String), + Boolean(bool), + Integer(i64), + Float(f64), + SubList(Vec), + Null, +} + +#[derive(Debug)] +pub struct Okml { + key: String, + value: OkmlType, +} + +impl Okml { + pub fn read_from_file(file_path: &str) -> Vec{ + let extension = &file_path[file_path.len()-4..file_path.len()]; + + if extension != "okml" { + println!("File is not in .okml {extension}"); + std::process::exit(-1); + } + println!("Okml File Loaded: {}", file_path); + + let mut content = fs::read_to_string(file_path) + .expect("Should've read the file"); + + let mut processed_content = pre_process(content.clone()); + + let re = Regex::new(r"[ \t\n]+").unwrap(); + let tokens: Vec<&str> = re.split(&processed_content).filter(|s| !s.is_empty()).collect(); + let (parsed_ast, _) = parse(tokens, 0); + parsed_ast + } + pub fn read_from_string(content: &str) -> Vec { + let mut processed_content = pre_process(content.to_string()); + let re = Regex::new(r"[ \t\n]+").unwrap(); + let tokens: Vec<&str> = re.split(&processed_content).filter(|s| !s.is_empty()).collect(); + let (parsed_ast, _) = parse(tokens, 0); + parsed_ast + } +} + +fn pre_process(mut content: String) -> String{ + let mut chars: Vec = content.chars().collect(); + let mut result = Vec::with_capacity(chars.len()); + let mut next_char: Option<&char>; + for (index, ¤t_char) in chars.iter().enumerate() { + next_char = chars.get(index+1); + if current_char == ' ' && next_char == Some(&':') { + continue; + } + + if current_char == ':' + && next_char != Some(&' ') + && chars.get(index.wrapping_sub(1)) != Some(&'\\') + { + result.push(current_char); + result.push(' '); + } else if current_char == '{' && chars.get(index-1) != Some(&' '){ + result.push(' '); + result.push(current_char); + } else if current_char == '`' && (next_char != Some(&'`')) { + result.push(current_char); + result.push('\n'); + } else if current_char == '`' && (chars.get(index-1) != Some(&'\n')) { + // result.push('\n'); + result.push(current_char); + } + else { + result.push(current_char); + } + } + + chars = result; + + let mut rc: String = chars.into_iter().collect(); + return rc; +} + + +fn parse(tokens: Vec<&str>, index: usize) -> (Vec, usize) { + let token_len = tokens.len(); + + let mut parent: Vec = Default::default(); + let count_braces: u64 = 0; + let mut index = 0; + while index < token_len-1 { + let current = tokens.get(index).unwrap(); + let mut value = tokens.get(index+1).unwrap(); + // parse (sub_list_key { ) + if value == &"{" { + let mut child: Vec = Default::default(); + let mut new_index = 0; + (child, new_index) = parse_list(tokens.clone(), index); + let mut child_to_push: Okml = Okml { + key: current.to_string(), + value: OkmlType::SubList(child) + }; + parent.push(child_to_push); + index = new_index-1; + continue; + } + + + // parse (key: value) + if let Some(':') = current.chars().last() { + if value == &"```" { + let mut _current: &str; + let mut result: String = Default::default(); + while index < token_len{ + index = index+1; + _current = tokens.get(index+1).unwrap(); + if _current == "```" { + break; + } + result.push_str(_current); + result.push_str(" "); + } + + parent.push(Okml{ + key: current.to_string(), + value: OkmlType::String(result.clone()) + }); + } else { + + let mut return_value: OkmlType; + match value { + &"true" | &"yes" => return_value = OkmlType::Boolean(true), + &"false" | &"no" => return_value = OkmlType::Boolean(false), + &"null" => return_value = OkmlType::Null, + &&_ => { + if let Ok(parsed) = value.parse::() { + return_value = OkmlType::Integer(parsed); + } else if let Ok(parsed) = value.parse::() { + return_value = OkmlType::Float(parsed); + } else { + return_value = OkmlType::String(value.to_string()); + } + } + } + // match value + parent.push(Okml{ + key: current.to_string(), + value: (return_value) + }); + } + } + index +=1 + } + + return (parent, index) +} + + + +fn parse_list(tokens: Vec<&str>, mut index: usize) -> (Vec, usize) { + let mut parent: Vec = Default::default(); + index = index +2; + let mut current = tokens.get(index).unwrap(); + if current == &"}" { + return (parent, index) + } + let mut value = tokens.get(index+1).unwrap(); + while current != &"}" { + current = tokens.get(index).unwrap(); + value = tokens.get(index+1).unwrap(); + if current == &"}" || value == &"}" { + break; + } + + if value == &"{" { + let mut new_index: usize = 0; + let mut child: Vec = Default::default(); + (child, new_index) = parse_list(tokens.clone(), index); + parent.push(Okml { + key: current.to_string(), + value: OkmlType::SubList(child) + }); + index = new_index-1; + } else { + // println!("{} => {} ", current, value); + if value == &"```" { + let mut _current: &str; + let mut result: String = Default::default(); + while index < tokens.len(){ + index = index+1; + _current = tokens.get(index+1).unwrap(); + if _current == "```" { + break; + } + result.push_str(_current); + result.push_str(" "); + } + + parent.push(Okml{ + key: current.to_string(), + value: OkmlType::String(result.clone()) + }); + } else { + let mut return_value: OkmlType; + match value { + &"true" | &"yes" => return_value = OkmlType::Boolean(true), + &"false" | &"no" => return_value = OkmlType::Boolean(false), + &"null" => return_value = OkmlType::Null, + &&_ => { + if let Ok(parsed) = value.parse::() { + return_value = OkmlType::Integer(parsed); + } else if let Ok(parsed) = value.parse::() { + return_value = OkmlType::Float(parsed); + } else { + return_value = OkmlType::String(value.to_string()); + } + } + } + // match value + parent.push(Okml{ + key: current.to_string(), + value: (return_value) + }); + } + } + index = index+2; + } + + + (parent, index) +} diff --git a/src/main.rs b/src/main.rs index c780348..e11c977 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,238 +1,4 @@ -#![allow(unused)] -use log::{debug, error, info, trace, warn}; -use std::fs; -use regex::Regex; - -#[derive(Debug)] -enum OkmlType { - String(String), - Boolean(bool), - Integer(i64), - Float(f64), - SubList(Vec), - Null, -} - -#[derive(Debug)] -struct Okml { - key: String, - value: OkmlType, -} - -impl Okml { - fn read_from_file(file_path: &str) -> Vec{ - let extension = &file_path[file_path.len()-4..file_path.len()]; - - if extension != "okml" { - error!("File is not in .okml {extension}"); - std::process::exit(-1); - } - info!("Okml File Loaded: {}", file_path); - - let mut content = fs::read_to_string(file_path) - .expect("Should've read the file"); - - let mut processed_content = pre_process(content.clone()); - - let re = Regex::new(r"[ \t\n]+").unwrap(); - let tokens: Vec<&str> = re.split(&processed_content).filter(|s| !s.is_empty()).collect(); - let (parsed_ast, _) = parse(tokens, 0); - parsed_ast - } - fn read_from_string(content: &str) -> Vec { - let mut processed_content = pre_process(content.to_string()); - let re = Regex::new(r"[ \t\n]+").unwrap(); - let tokens: Vec<&str> = re.split(&processed_content).filter(|s| !s.is_empty()).collect(); - let (parsed_ast, _) = parse(tokens, 0); - parsed_ast - } -} - -fn pre_process(mut content: String) -> String{ - let mut chars: Vec = content.chars().collect(); - let mut result = Vec::with_capacity(chars.len()); - let mut next_char: Option<&char>; - for (index, ¤t_char) in chars.iter().enumerate() { - next_char = chars.get(index+1); - if current_char == ' ' && next_char == Some(&':') { - continue; - } - - if current_char == ':' - && next_char != Some(&' ') - && chars.get(index.wrapping_sub(1)) != Some(&'\\') - { - result.push(current_char); - result.push(' '); - } else if current_char == '{' && chars.get(index-1) != Some(&' '){ - result.push(' '); - result.push(current_char); - } else if current_char == '`' && (next_char != Some(&'`')) { - result.push(current_char); - result.push('\n'); - } else if current_char == '`' && (chars.get(index-1) != Some(&'\n')) { - // result.push('\n'); - result.push(current_char); - } - else { - result.push(current_char); - } - } - - chars = result; - - let mut rc: String = chars.into_iter().collect(); - return rc; -} - - -fn parse(tokens: Vec<&str>, index: usize) -> (Vec, usize) { - let token_len = tokens.len(); - - let mut parent: Vec = Default::default(); - let count_braces: u64 = 0; - let mut index = 0; - while index < token_len-1 { - let current = tokens.get(index).unwrap(); - let mut value = tokens.get(index+1).unwrap(); - // parse (sub_list_key { ) - if value == &"{" { - let mut child: Vec = Default::default(); - let mut new_index = 0; - (child, new_index) = parse_list(tokens.clone(), index); - let mut child_to_push: Okml = Okml { - key: current.to_string(), - value: OkmlType::SubList(child) - }; - parent.push(child_to_push); - index = new_index-1; - continue; - } - - - // parse (key: value) - if let Some(':') = current.chars().last() { - if value == &"```" { - let mut _current: &str; - let mut result: String = Default::default(); - while index < token_len{ - index = index+1; - _current = tokens.get(index+1).unwrap(); - if _current == "```" { - break; - } - result.push_str(_current); - result.push_str(" "); - } - - parent.push(Okml{ - key: current.to_string(), - value: OkmlType::String(result.clone()) - }); - } else { - - let mut return_value: OkmlType; - match value { - &"true" | &"yes" => return_value = OkmlType::Boolean(true), - &"false" | &"no" => return_value = OkmlType::Boolean(false), - &"null" => return_value = OkmlType::Null, - &&_ => { - if let Ok(parsed) = value.parse::() { - return_value = OkmlType::Integer(parsed); - } else if let Ok(parsed) = value.parse::() { - return_value = OkmlType::Float(parsed); - } else { - return_value = OkmlType::String(value.to_string()); - } - } - } - // match value - parent.push(Okml{ - key: current.to_string(), - value: (return_value) - }); - } - } - index +=1 - } - - return (parent, index) -} - - - -fn parse_list(tokens: Vec<&str>, mut index: usize) -> (Vec, usize) { - let mut parent: Vec = Default::default(); - index = index +2; - let mut current = tokens.get(index).unwrap(); - if current == &"}" { - return (parent, index) - } - let mut value = tokens.get(index+1).unwrap(); - while current != &"}" { - current = tokens.get(index).unwrap(); - value = tokens.get(index+1).unwrap(); - if current == &"}" || value == &"}" { - break; - } - - if value == &"{" { - let mut new_index: usize = 0; - let mut child: Vec = Default::default(); - (child, new_index) = parse_list(tokens.clone(), index); - parent.push(Okml { - key: current.to_string(), - value: OkmlType::SubList(child) - }); - index = new_index-1; - } else { - // println!("{} => {} ", current, value); - if value == &"```" { - let mut _current: &str; - let mut result: String = Default::default(); - while index < tokens.len(){ - index = index+1; - _current = tokens.get(index+1).unwrap(); - if _current == "```" { - break; - } - result.push_str(_current); - result.push_str(" "); - } - - parent.push(Okml{ - key: current.to_string(), - value: OkmlType::String(result.clone()) - }); - } else { - let mut return_value: OkmlType; - match value { - &"true" | &"yes" => return_value = OkmlType::Boolean(true), - &"false" | &"no" => return_value = OkmlType::Boolean(false), - &"null" => return_value = OkmlType::Null, - &&_ => { - if let Ok(parsed) = value.parse::() { - return_value = OkmlType::Integer(parsed); - } else if let Ok(parsed) = value.parse::() { - return_value = OkmlType::Float(parsed); - } else { - return_value = OkmlType::String(value.to_string()); - } - } - } - // match value - parent.push(Okml{ - key: current.to_string(), - value: (return_value) - }); - } - } - index = index+2; - } - - - (parent, index) -} +use okaml::Okml; // Driver Code fn main() { -- cgit v1.2.3