From 4d9d78f4caa998b4817de2d77c0f7362de318c52 Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Thu, 25 Jan 2024 22:21:41 +0000 Subject: [PATCH 1/4] fix(dynamic string): ironvar parser being too greedy --- src/dynamic_value/dynamic_string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynamic_value/dynamic_string.rs b/src/dynamic_value/dynamic_string.rs index ea2eb39b..fe522937 100644 --- a/src/dynamic_value/dynamic_string.rs +++ b/src/dynamic_value/dynamic_string.rs @@ -155,7 +155,7 @@ fn parse_variable(chars: &[char]) -> (DynamicStringSegment, usize) { let str = chars .iter() .skip(1) - .take_while(|&c| !c.is_whitespace()) + .take_while(|&c| c.is_ascii_alphanumeric() || c == &'_' || c == &'-') .collect::(); let len = str.chars().count() + SKIP_HASH; From af7e037dd5a24cff0959e2fd5f04e3eb49418b23 Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Thu, 25 Jan 2024 22:22:16 +0000 Subject: [PATCH 2/4] test(dynamic string): test pango attributes with ironvars --- src/dynamic_value/dynamic_string.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/dynamic_value/dynamic_string.rs b/src/dynamic_value/dynamic_string.rs index fe522937..cad4b3da 100644 --- a/src/dynamic_value/dynamic_string.rs +++ b/src/dynamic_value/dynamic_string.rs @@ -316,4 +316,18 @@ mod tests { matches!(&tokens[0], DynamicStringSegment::Script(script) if script.cmd == "echo #hello") ); } + + #[test] + fn test_pango_attribute() { + const INPUT: &str = "hello"; + let (tokens, _) = parse_input(INPUT); + + assert_eq!(tokens.len(), 3); + + assert!(matches!(&tokens[0], DynamicStringSegment::Static(str) if str == "hello")) + } } From 63304a9ddd76b2274b8336eba7e1e5ef7c5d66e6 Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Thu, 25 Jan 2024 22:22:57 +0000 Subject: [PATCH 3/4] fix(dynamic string): always sending partial string on initialization --- src/dynamic_value/dynamic_string.rs | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/dynamic_value/dynamic_string.rs b/src/dynamic_value/dynamic_string.rs index cad4b3da..6c0cfb52 100644 --- a/src/dynamic_value/dynamic_string.rs +++ b/src/dynamic_value/dynamic_string.rs @@ -29,7 +29,7 @@ pub fn dynamic_string(input: &str, mut f: F) where F: FnMut(String) + 'static, { - let tokens = parse_input(input); + let (tokens, is_static) = parse_input(input); let label_parts = arc_mut!(vec![]); let (tx, rx) = mpsc::channel(32); @@ -91,17 +91,17 @@ where glib_recv_mpsc!(rx , val => f(val)); // initialize - { + if is_static { let label_parts = lock!(label_parts).join(""); try_send!(tx, label_parts); } } /// Parses the input string into static and dynamic segments -fn parse_input(input: &str) -> Vec { +fn parse_input(input: &str) -> (Vec, bool) { // short-circuit parser if it's all static if !input.contains("{{") && !input.contains('#') { - return vec![DynamicStringSegment::Static(input.to_string())]; + return (vec![DynamicStringSegment::Static(input.to_string())], true); } let mut tokens = vec![]; @@ -129,7 +129,7 @@ fn parse_input(input: &str) -> Vec { chars.drain(..skip); } - tokens + (tokens, false) } fn parse_script(chars: &[char]) -> (DynamicStringSegment, usize) { @@ -190,7 +190,7 @@ mod tests { #[test] fn test_static() { const INPUT: &str = "hello world"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 1); assert!(matches!(&tokens[0], DynamicStringSegment::Static(value) if value == INPUT)) @@ -199,7 +199,7 @@ mod tests { #[test] fn test_static_odd_char_count() { const INPUT: &str = "hello"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 1); assert!(matches!(&tokens[0], DynamicStringSegment::Static(value) if value == INPUT)) @@ -208,7 +208,7 @@ mod tests { #[test] fn test_script() { const INPUT: &str = "{{echo hello}}"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 1); assert!( @@ -219,7 +219,7 @@ mod tests { #[test] fn test_variable() { const INPUT: &str = "#variable"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 1); assert!( @@ -230,7 +230,7 @@ mod tests { #[test] fn test_static_script() { const INPUT: &str = "hello {{echo world}}"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 2); assert!(matches!(&tokens[0], DynamicStringSegment::Static(str) if str == "hello ")); @@ -242,7 +242,7 @@ mod tests { #[test] fn test_static_variable() { const INPUT: &str = "hello #subject"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 2); assert!(matches!(&tokens[0], DynamicStringSegment::Static(str) if str == "hello ")); @@ -254,7 +254,7 @@ mod tests { #[test] fn test_static_script_static() { const INPUT: &str = "hello {{echo world}} foo"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 3); assert!(matches!(&tokens[0], DynamicStringSegment::Static(str) if str == "hello ")); @@ -267,7 +267,7 @@ mod tests { #[test] fn test_static_variable_static() { const INPUT: &str = "hello #subject foo"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 3); assert!(matches!(&tokens[0], DynamicStringSegment::Static(str) if str == "hello ")); @@ -280,7 +280,7 @@ mod tests { #[test] fn test_static_script_variable() { const INPUT: &str = "hello {{echo world}} #foo"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 4); assert!(matches!(&tokens[0], DynamicStringSegment::Static(str) if str == "hello ")); @@ -296,7 +296,7 @@ mod tests { #[test] fn test_escape_hash() { const INPUT: &str = "number ###num"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 3); assert!(matches!(&tokens[0], DynamicStringSegment::Static(str) if str == "number ")); @@ -309,7 +309,7 @@ mod tests { #[test] fn test_script_with_hash() { const INPUT: &str = "{{echo #hello}}"; - let tokens = parse_input(INPUT); + let (tokens, _) = parse_input(INPUT); assert_eq!(tokens.len(), 1); assert!( From 9d7cb08f41e7290959e17ccd725aeb6ccaeef1a7 Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Thu, 25 Jan 2024 22:30:53 +0000 Subject: [PATCH 4/4] docs(ironvars): correct allowed chars in keys --- docs/Ironvars.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Ironvars.md b/docs/Ironvars.md index ae758068..975fd55b 100644 --- a/docs/Ironvars.md +++ b/docs/Ironvars.md @@ -1,7 +1,7 @@ Ironvars are runtime variables that can be referenced in several places in your config, then set using the IPC server (such as via the CLI) using the `set` command. -Any UTF-8 string *without whitespace* is a valid key. +Keys can consist of alphanumeric characters, `-` and `_` only. Any UTF-8 string is a valid value. Reference values using `#my_variable`. These update as soon as the value changes.