keyvalues-serde is a (de)serialization library for
VDF text v1
built on the serde framework. This library
leverages keyvalues-parser for parsing and rendering the keyvalues text. This
makes it easy to deal with VDF text files using strongly typed Rust structures.
Just add the library to your Cargo.toml
$ cargo add keyvalues-serde$ cargo add keyvalues-serde
$ cargo add serde --features deriveuse serde::Deserialize;
// Contents take from my ~/.data/Steam/steam/games/PlatformMenu.vdf
const VDF_TEXT: &str = r##"
// this file defines the contents of the platform menu
"Platform"
{
"Menu"
{
"Games"
{
"dll" "steamui"
"interface" "SteamUIGames001"
"MenuName" "#Steam_Games"
"SteamApp" "1"
}
"Friends"
{
"dll" "bin/friendsui"
"interface" "VGuiModuleTracker001"
"MenuName" "#App_Friends"
}
"Servers"
{
"dll" "bin/serverbrowser"
"interface" "VGuiModuleServerBrowser001"
"MenuName" "#App_Servers"
}
"Settings"
{
"dll" "steamui"
"interface" "VGuiModuleSettings001"
"MenuName" "#App_Settings"
"SteamApp" "1"
}
}
}
"##;
#[derive(Deserialize, Debug)]
struct Platform {
#[serde(rename = "Menu")]
menu: Menu,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
struct Menu {
games: MenuModule,
friends: MenuModule,
servers: MenuModule,
settings: MenuModule,
}
#[derive(Deserialize, Debug)]
struct MenuModule {
dll: String,
interface: String,
#[serde(rename = "MenuName")]
menu_name: String,
#[serde(rename = "SteamApp")]
steam_app: Option<bool>,
}
fn main() -> keyvalues_serde::Result<()> {
let platform: Platform = keyvalues_serde::from_str(VDF_TEXT)?;
println!("{:#?}", platform);
Ok(())
}- Primitive Types
booli8,i16,i32,i64,i128u8,u16,u32,u64,u128f32,f64char
StringOption- VDF doesn't have the concept of a
nulltype, so an optional value is consideredSomeif present andNoneif missing
- VDF doesn't have the concept of a
- Unit Variant Enum
- Represented as text matching the variant name
- Newtype Struct
- Considered just a wrapper over the contained data type
- Homogeneous Sequences (
Vec-like types)- Represented as several pairs with the same key
- Heterogeneous Sequences (
tuple-like types)- Represented as several pairs with the same key
- TupleStruct
- Considered a wrapper over the contained tuple
- Map (
HashMap-like types)- Represented by a list of pairs contained within curly-braces
{}
- Represented by a list of pairs contained within curly-braces
- Struct
- The same as Map. The name of the struct is ignored unless it's the used for the top-level key
| Type | Reasoning |
|---|---|
| Byte Array | No clear VDF representation |
| Unit | No clear VDF representation |
| Unit Struct | No clear VDF representation |
| Enum-containers (newtype, tuple, and struct variants) | The only clear usage would be the untagged representation in which case the ambiguity of types (everything is essentially just strings or objects) allows for too many footguns for me to be comfortable supporting |
- Any sequence types containing
Options may lead to unexpected ordering issues since aNoneis just omitted- For instance a tuple containing an
Optionin the middle will be very problematic
- For instance a tuple containing an
- Empty
Vecs andOptions withNoneare both omitted when serializing. - Nested sequences are impossible to represent due to the limited nature of sequences in VDF (AFAIK)
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.