Skip to content

Commit

Permalink
feat: trailing semicolon is now optional
Browse files Browse the repository at this point in the history
  • Loading branch information
amunra committed Apr 11, 2024
1 parent ab879c1 commit 8dffd91
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 19 deletions.
6 changes: 3 additions & 3 deletions questdb-confstr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ service::key1=value1;key2=value2;key3=value3;
```

A few rules:
* The last semicolon is mandatory.
* The last semicolon is optional.
* Service name and keys are case-sensitive.
* Keys are ASCII alphanumeric and can contain underscores.
* Values are case-sensitive unicode strings which can contain any characters,
Expand All @@ -21,10 +21,10 @@ A few rules:

## Grammar

```plain
```json
conf_str ::= service "::" params | service
service ::= identifier
params ::= param (";" param)* ";"
params ::= param (";" param)* ";"?
param ::= key "=" value
key ::= identifier
value ::= { value_char }
Expand Down
7 changes: 3 additions & 4 deletions questdb-confstr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ fn parse_ident(
fn parse_value(
iter: &mut Peekable2<CharIndices>,
next_pos: &mut Position,
input_len: usize,
) -> Result<Value, ParsingError> {
let mut value = String::new();
loop {
Expand All @@ -220,7 +219,7 @@ fn parse_value(
value.push(c);
let _ = iter.next();
}
(None, _) => return Err(parse_err(ErrorKind::MissingTrailingSemicolon, input_len)),
(None, _) => break,
}
}
Ok(value)
Expand Down Expand Up @@ -262,8 +261,8 @@ fn parse_params(
Some((p, c)) => return Err(parse_err(ErrorKind::BadSeparator(('=', c)), p)),
None => return Err(parse_err(ErrorKind::IncompleteKeyValue, input_len)),
}
let value = parse_value(iter, next_pos, input_len)?;
iter.next().unwrap(); // skip ';'
let value = parse_value(iter, next_pos)?;
iter.next(); // skip ';', if present.
params.insert(key, value);
}
Ok(params)
Expand Down
20 changes: 8 additions & 12 deletions questdb-confstr/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,23 +259,19 @@ fn test_incomplete_key_no_value() {
#[test]
fn missing_trailing_semicolon() {
let input = "http::host=localhost;port=9000";
let config = parse_conf_str(input);
assert!(config.is_err());
let err = config.unwrap_err();
assert_eq!(ErrorKind::MissingTrailingSemicolon, err.kind());
assert_eq!(err.position(), 30);
assert_eq!(err.to_string(), "missing trailing semicolon at position 30");
let config = parse_conf_str(input).unwrap();
assert_eq!(config.service(), "http");
assert_eq!(config.get("host"), Some("localhost"));
assert_eq!(config.get("port"), Some("9000"));
}

#[test]
fn escaped_semicolon_missing_trailing() {
let input = "http::host=localhost;port=9000;;";
let config = parse_conf_str(input);
assert!(config.is_err());
let err = config.unwrap_err();
assert_eq!(err.kind(), ErrorKind::MissingTrailingSemicolon);
assert_eq!(err.position(), 32);
assert_eq!(err.to_string(), "missing trailing semicolon at position 32");
let config = parse_conf_str(input).unwrap();
assert_eq!(config.service(), "http");
assert_eq!(config.get("host"), Some("localhost"));
assert_eq!(config.get("port"), Some("9000;"));
}

#[test]
Expand Down

0 comments on commit 8dffd91

Please sign in to comment.