2 releases
0.1.1 | Jun 26, 2024 |
---|---|
0.1.0 | Jun 24, 2024 |
#591 in Parser implementations
79KB
1.5K
SLoC
VDFLex
VDFLex is a (de)serialization library for parsing the Valve Data File format with serde. VDF—or more generally, KeyValues—is a data format developed by Valve for use in Steam and the Source engine.
LightmappedGeneric
{
$basetexture "myassets\gravel01"
$surfaceprop gravel
}
Installation
Add the following to your project's Cargo.toml
:
[dependencies]
serde = { version = "1.0.0", features = ["derive"] }
vdflex = "0.1.1"
Feature Flags
default
: No featurespreserve_order
: Preserve entry insertion order
Quick Start
use std::collections::BTreeMap;
use std::hash::Hash;
use serde::Serialize;
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize)]
struct AppId(u32);
#[derive(Serialize)]
#[serde(rename_all = "PascalCase")]
struct AppBuild {
#[serde(rename = "AppID")]
app_id: AppId,
desc: String,
content_root: String,
build_output: String,
depots: BTreeMap<AppId, Depot>
}
#[derive(Serialize)]
struct Depot {
#[serde(rename = "FileMapping")]
file_mappings: Vec<FileMapping>
}
#[derive(Serialize)]
struct FileMapping {
#[serde(rename = "LocalPath")]
local_path: String,
#[serde(rename = "DepotPath")]
depot_path: String,
}
fn main() -> vdflex::Result<()> {
let mut depots = BTreeMap::new();
depots.insert(AppId(1234), Depot {
file_mappings: vec![FileMapping {
local_path: String::from("*"),
depot_path: String::from("."),
}],
});
let build_script = AppBuild {
app_id: AppId(1234),
desc: String::from("My SteamPipe build script"),
content_root: String::from("..\\assets\\"),
build_output: String::from("..\\build\\"),
depots,
};
let text: String = vdflex::kv_to_string("AppBuild", &build_script)?;
println!("{text}");
// "AppBuild"
// {
// "AppID" "1234"
// "BuildOutput" "..\build\"
// "ContentRoot" "..\assets\"
// "Depots"
// "Desc" "My SteamPipe build script"
// {
// "1234"
// {
// "FileMapping"
// {
// "DepotPath" "."
// "LocalPath" "*"
// }
// }
// }
// }
Ok(())
}
Supported Types
KeyValues is woefully underspecified, but in general it only supports strings and multimaps (objects). VDFLex attempts to support every Rust type, but not all types necessarily have an "idiomatic" or "useful" representation. These are the types that VDFlex supports and how they are represented in KeyValues:
Type | Notes |
---|---|
bool |
Serialized to 1 or 0 |
integers | KeyValues doesn't typically support i128 or u128 |
f32 /f64 |
Some implementations only support f32 . Non-finite floats are also poorly supported. |
char /String /str |
- |
Option |
KeyValues has no equivalent of null , so Some<T> is represented as T and None is simply omitted |
Unit/Unit Structs | Serialized like None |
Unit Variants | Represented as a string matching the name of the variant |
Newtype Structs | Represented as the wrapped type |
Newtype Variants | Represented as an object mapping the variant name to the wrapped type |
Sequences/Tuples/Tuple Structs | Represented by repeating the key for each element in the sequence |
Tuple Variants | Represented by a map containing a sequence of the tuple's fields, using the variant name as the key |
Maps/Structs | Represented by objects (a curly bracket-enclosed list of key-value pairs) |
Struct Variants | Represented as an object mapping the variant name to the struct representation of its fields |
Limitations
- The Bytes type is unsupported, as there is no clear way to represent binary data in KeyValues.
- Sequences are weird. It's not possible to serialize top-level or nested sequences. See
Error::UnrepresentableSequence
for more.
Missing Features
This library is in an early state. As such, many features have not yet been implemented. Some missing features include:
- Deserialization
- Text parsing
- Conversion to Rust types
- An easier API for
Object
- A
keyvalues!
macro to createObject
s - Conditional tags
- The
ser::Formatter
API supports conditional tags, but this is unsupported for the serde API.
- The
#base
and#include
directives- The
ser::Formatter
API supports macro formatting, but the serde API treats macros like normal fields.
- The
License
This library is licensed under the MIT license (https://opensource.org/license/MIT).
Dependencies
~0.4–1.1MB
~25K SLoC