Module string

Source
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

KeyTypeDefaultComment
"lengthEncoding"object{ "type": "tillend" }The way the length of the string is communicated
"minLength"uintoptionalMinimal length of the string
"maxLength"uintoptionalMaximal length of the string
"format"stringoptionalSpecial 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§

DecodingError
Errors decoding a string with a StringSchema.
EncodingError
Errors encoding a string with a StringSchema.
StringSchema
The string schema to describe string values (further information on the module’s documentation).
ValidationError
Errors validating a StringSchema.