diff options
| author | Mike Buland <mike@xagasoft.com> | 2026-06-08 21:45:30 -0700 |
|---|---|---|
| committer | Mike Buland <mike@xagasoft.com> | 2026-06-08 21:45:30 -0700 |
| commit | 0f2bd09d269862105e603a9865201f521f49490b (patch) | |
| tree | 5326c452c41b5bd4a521ad5fa216dd999f31b5f8 /src/lib.rs | |
| parent | 0736240f54ac90ded4d96b3ac35fc8571b141d1a (diff) | |
| download | crimtag-0f2bd09d269862105e603a9865201f521f49490b.tar.gz crimtag-0f2bd09d269862105e603a9865201f521f49490b.tar.bz2 crimtag-0f2bd09d269862105e603a9865201f521f49490b.tar.xz crimtag-0f2bd09d269862105e603a9865201f521f49490b.zip | |
It works again! and more!
About to change a few things:
- symbols and errors will have a range not a position
- remove view/output token type, those should just be View and Output
structs
- Figure out some formatting stuff? (add a dep? I dunno)
- Move to non-quoted dot-delimeted variable references.
- Add loops.
- Add conditionals?
- Add more!
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 80 |
1 files changed, 46 insertions, 34 deletions
| @@ -5,22 +5,10 @@ use std::time::SystemTime; | |||
| 5 | 5 | ||
| 6 | mod lexer; | 6 | mod lexer; |
| 7 | mod parser; | 7 | mod parser; |
| 8 | mod position; | ||
| 8 | 9 | ||
| 9 | pub use parser::ParseError; | 10 | pub use parser::ParseError; |
| 10 | 11 | pub use position::*; | |
| 11 | #[derive(Debug,Copy,Clone)] | ||
| 12 | pub struct Position { | ||
| 13 | pub line: u32, | ||
| 14 | pub column: u32, | ||
| 15 | } | ||
| 16 | |||
| 17 | impl Position { | ||
| 18 | pub fn new( line: u32, column: u32 ) -> Self { | ||
| 19 | Self { | ||
| 20 | line, column, | ||
| 21 | } | ||
| 22 | } | ||
| 23 | } | ||
| 24 | 12 | ||
| 25 | #[derive(Debug)] | 13 | #[derive(Debug)] |
| 26 | pub struct Crimtag { | 14 | pub struct Crimtag { |
| @@ -29,7 +17,7 @@ pub struct Crimtag { | |||
| 29 | } | 17 | } |
| 30 | 18 | ||
| 31 | #[derive(PartialEq,Eq,Debug,Clone)] | 19 | #[derive(PartialEq,Eq,Debug,Clone)] |
| 32 | enum ViewSource { | 20 | pub enum ViewSource { |
| 33 | File { | 21 | File { |
| 34 | path: PathBuf, | 22 | path: PathBuf, |
| 35 | loaded: SystemTime, | 23 | loaded: SystemTime, |
| @@ -52,7 +40,7 @@ impl View { | |||
| 52 | fn process(&self, input: &Value) -> Result<Value, ParseError> { | 40 | fn process(&self, input: &Value) -> Result<Value, ParseError> { |
| 53 | let mut out_vars = HashMap::new(); | 41 | let mut out_vars = HashMap::new(); |
| 54 | for output in &self.outputs { | 42 | for output in &self.outputs { |
| 55 | if let Token::Output(_,_,tokens) = &output.ast_root { | 43 | if let Token::Output(_,/*_,*/tokens) = &output.ast_root { |
| 56 | let mut buf = String::new(); | 44 | let mut buf = String::new(); |
| 57 | exec( input, tokens, &mut buf )?; | 45 | exec( input, tokens, &mut buf )?; |
| 58 | out_vars.insert( output.name.clone(), Value::String(buf) ); | 46 | out_vars.insert( output.name.clone(), Value::String(buf) ); |
| @@ -74,17 +62,9 @@ type Properties = HashMap<String, String>; | |||
| 74 | enum Token { | 62 | enum Token { |
| 75 | Root(Vec<Token>), | 63 | Root(Vec<Token>), |
| 76 | View(String,Properties,Vec<Token>), | 64 | View(String,Properties,Vec<Token>), |
| 77 | Output(String,Properties,Vec<Token>), | 65 | Output(String,/*Properties,*/ Vec<Token>), |
| 78 | Show(String,Properties), | 66 | Show(String,Properties), |
| 79 | Text(String), | 67 | Text(String), |
| 80 | Literal(String), | ||
| 81 | /* | ||
| 82 | Tag{ | ||
| 83 | name: String, | ||
| 84 | params: Vec<String>, | ||
| 85 | props: Properties, | ||
| 86 | children: Vec<Token> | ||
| 87 | },*/ | ||
| 88 | } | 68 | } |
| 89 | 69 | ||
| 90 | #[derive(Debug)] | 70 | #[derive(Debug)] |
| @@ -203,6 +183,18 @@ impl Crimtag { | |||
| 203 | } | 183 | } |
| 204 | } | 184 | } |
| 205 | 185 | ||
| 186 | pub fn get_view_source(&self, view: &str) -> Option<ViewSource> { | ||
| 187 | if let Some(view) = self.views.get(view) { | ||
| 188 | if view.source < self.sources.len() { | ||
| 189 | Some(self.sources[view.source].clone()) | ||
| 190 | } else { | ||
| 191 | None | ||
| 192 | } | ||
| 193 | } else { | ||
| 194 | None | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 206 | pub fn view_partial(&self, view: &str, input: &Value ) -> Result<Value,ParseError> { | 198 | pub fn view_partial(&self, view: &str, input: &Value ) -> Result<Value,ParseError> { |
| 207 | if let Some(view) = self.views.get(view) { | 199 | if let Some(view) = self.views.get(view) { |
| 208 | return view.process( input ) | 200 | return view.process( input ) |
| @@ -213,12 +205,10 @@ impl Crimtag { | |||
| 213 | 205 | ||
| 214 | pub fn view(&self, view: &str, input: &Value ) -> Result<String,ParseError> { | 206 | pub fn view(&self, view: &str, input: &Value ) -> Result<String,ParseError> { |
| 215 | if let Some(view) = self.views.get( view ) { | 207 | if let Some(view) = self.views.get( view ) { |
| 216 | let mut output = view.process( input )?; | 208 | let output = view.process( input )?; |
| 217 | if let Some(l) = &view.layout { | 209 | if let Some(l) = &view.layout { |
| 218 | println!("Layout: {}", l ); | ||
| 219 | self.view( l, &output ) | 210 | self.view( l, &output ) |
| 220 | } else { | 211 | } else { |
| 221 | println!("No layout, at the top"); | ||
| 222 | if let Value::Dictionary(mut d) = output && | 212 | if let Value::Dictionary(mut d) = output && |
| 223 | let Some(content) = d.remove("content") && | 213 | let Some(content) = d.remove("content") && |
| 224 | let Value::String(s) = content { | 214 | let Value::String(s) = content { |
| @@ -242,18 +232,40 @@ fn exec(input: &Value, tokens: &Vec<Token>, buf: &mut String) -> Result<(),Parse | |||
| 242 | println!("Too high!?"); | 232 | println!("Too high!?"); |
| 243 | // Error? | 233 | // Error? |
| 244 | } | 234 | } |
| 245 | Token::Show(s,_) => { | 235 | Token::Show(s,p) => { |
| 236 | let format = if let Some(s) = p.get("format") { | ||
| 237 | s | ||
| 238 | } else { | ||
| 239 | &"".to_string() | ||
| 240 | }; | ||
| 246 | if let Value::Dictionary(d) = input && | 241 | if let Value::Dictionary(d) = input && |
| 247 | let Some(Value::String(s)) = d.get(s) { | 242 | let Some(value) = d.get(s) { |
| 248 | buf.push_str(s); | 243 | match value { |
| 244 | Value::Dictionary(_) => { | ||
| 245 | buf.push_str("<dictionary>"); | ||
| 246 | } | ||
| 247 | Value::List(_) => { | ||
| 248 | buf.push_str("<list>"); | ||
| 249 | } | ||
| 250 | Value::String(s) => { | ||
| 251 | buf.push_str(s); | ||
| 252 | } | ||
| 253 | Value::Int(i) => { | ||
| 254 | buf.push_str(&i.to_string()); | ||
| 255 | } | ||
| 256 | Value::Float(f) => { | ||
| 257 | if format == "" { | ||
| 258 | buf.push_str(&f.to_string()); | ||
| 259 | } else { | ||
| 260 | buf.push_str(&f.to_string()); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | } | ||
| 249 | } | 264 | } |
| 250 | } | 265 | } |
| 251 | Token::Text(s) => { | 266 | Token::Text(s) => { |
| 252 | buf.push_str( s ); | 267 | buf.push_str( s ); |
| 253 | } | 268 | } |
| 254 | Token::Literal(..) => { | ||
| 255 | println!("Literal!?"); | ||
| 256 | } | ||
| 257 | } | 269 | } |
| 258 | } | 270 | } |
| 259 | Ok(()) | 271 | Ok(()) |
