Expand description
Implementation of the string schema
Strings are not used very often when handling binary data. However, strings have by nature no fixed length. Accordingly, there are several ways to encode the length of a string.
Furthermore, hex-encoded strings can be used to give a more human-readable version of raw bytes. Accordingly, the BDS codec allows to map between hex-encoded strings and raw bytes.
§Length of a String
The length of a string is the number of bytes required to store the UTF-8 string, e.g. "ß"
is UTF-8 encoded as 0xC39F
so the length of "ß"
is 2.
§Parameters
Key | Type | Default | Comment |
---|---|---|---|
"lengthEncoding" | object | { "type": "tillend" } | The way the length of the string is communicated |
"minLength" | uint | optional | Minimal length of the string |
"maxLength" | uint | optional | Maximal length of the string |
"format" | string | optional | Special format of the string |
§Validation
"lengthEncoding"
has its own validation rules (see LengthEncoding
).
This also includes the validity of the values of "minLength"
and "maxLength"
.
At the moment the only value for "format"
that is recognized by BDS is "binary"
(cf. binary format).
§Features
§Binary Format
When handling binary data it is common to display such data as hex-encoded strings, e.g. 0d7f
.
BDS supports the format "binary"
to simulate this.
Format "binary"
means that a JSON string is limited to lower-case hex-digits [a-f0-9]*
with an even length.
While encoding two hex-digits are encoded as one byte.
Accordingly, when decoding one byte in the byte string results in two hex-digits in the representing JSON string.
§Example
let schema = json!({
"type": "string",
"format": "binary"
});
let mut scope = json_schema::Scope::new();
let j_schema = scope.compile_and_return(schema.clone(), false)?;
let schema = from_value::<DataSchema>(schema)?;
let value = json!("deadbeaf42");
assert!(j_schema.validate(&value).is_valid());
let mut encoded = Vec::new();
schema.encode(&mut encoded, &value)?;
let expected = [ 0xde, 0xad, 0xbe, 0xaf, 0x42 ];
assert_eq!(&expected, encoded.as_slice());
let mut encoded = std::io::Cursor::new(encoded);
let back = schema.decode(&mut encoded)?;
assert!(j_schema.validate(&back).is_valid());
assert_eq!(back, value);
§Encoding Magic Bytes
When binary data is used for communication less secure protocols tend to use special bytes to mark beginning and end of a message.
We recommend to model this kind of magic bytes by combining the "default"
feature and "binary"
-format strings.
§Example
let schema = json!({
"type": "string",
"format": "binary",
"minLength": 4,
"maxLength": 4,
"default": "be42",
});
let mut scope = json_schema::Scope::new();
let j_schema = scope.compile_and_return(schema.clone(), false)?;
let schema = from_value::<DataSchema>(schema)?;
// Note: '{}' is not a valid value for the JSON schema
// but the interface requires a value.
let value = json!({});
let mut encoded = Vec::new();
schema.encode(&mut encoded, &value)?;
let expected = [ 0xbe, 0x42 ];
assert_eq!(&expected, encoded.as_slice());
let mut encoded = std::io::Cursor::new(encoded);
let back = schema.decode(&mut encoded)?;
assert!(j_schema.validate(&back).is_valid());
let expected = json!("be42");
assert_eq!(back, expected);
Enums§
- Decoding
Error - Errors decoding a string with a StringSchema.
- Encoding
Error - Errors encoding a string with a StringSchema.
- String
Schema - The string schema to describe string values (further information on the module’s documentation).
- Validation
Error - Errors validating a StringSchema.