Values, Cleaning, Docs, Tests, Example (Current Example is Wrong)

This commit is contained in:
Alex Emmet 2026-06-22 23:29:18 +02:00
commit c2a7afe6c1
37 changed files with 1693 additions and 520 deletions

View file

@ -1,9 +1,40 @@
pub const INTERNAL_COMM_RESERVED: std::ops::Range<u16> = 0..32;
pub const INTERNAL_DATA_RESERVED: std::ops::Range<u16> = 0..32;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CommunicationTypeId(pub u16);
impl CommunicationTypeId {
pub fn try_new(id: u16) -> Result<Self, ()> {
if INTERNAL_COMM_RESERVED.contains(&id) {
Err(())
} else {
Ok(Self(id))
}
}
pub fn is_reserved(&self) -> bool {
INTERNAL_COMM_RESERVED.contains(&self.0)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct DataTypeId(pub u16);
impl DataTypeId {
pub fn try_new(id: u16) -> Result<Self, ()> {
if INTERNAL_DATA_RESERVED.contains(&id) {
Err(())
} else {
Ok(Self(id))
}
}
pub fn is_reserved(&self) -> bool {
INTERNAL_DATA_RESERVED.contains(&self.0)
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Version(pub u16, pub u16);
@ -43,3 +74,109 @@ impl TypeMap {
}
include!(concat!(env!("OUT_DIR"), "/types.rs"));
/* ============================= REGISTRY ============================= */
#[cfg(feature = "registry")]
pub use registry::*;
#[cfg(feature = "registry")]
mod registry {
use std::collections::BTreeMap;
use crate::{Version, TypeMap, builtin_type_maps};
/*
* Multi-version type-map registry.
*
* Stores one `TypeMap` per protocol version and provides version
* negotiation for the host. Hosts build this from the compiled-in
* type maps (via `Registry::builtin()` or programmatically).
*/
#[derive(Clone, Debug)]
pub struct Registry {
versions: BTreeMap<Version, TypeMap>,
}
impl Registry {
pub fn new() -> Self {
Self {
versions: BTreeMap::new(),
}
}
pub fn register(&mut self, typemap: TypeMap) {
self.versions.insert(typemap.version.clone(), typemap);
}
pub fn get(&self, version: &Version) -> Option<&TypeMap> {
self.versions.get(version)
}
pub fn supports(&self, version: &Version) -> bool {
self.versions.contains_key(version)
}
pub fn negotiate(&self, client_versions: &[Version]) -> Option<Version> {
client_versions
.iter()
.filter(|v| self.versions.contains_key(v))
.max()
.cloned()
}
pub fn latest(&self) -> Option<&TypeMap> {
self.versions.last_key_value().map(|(_, v)| v)
}
pub fn builtin() -> Self {
let mut r = Self::new();
for tm in builtin_type_maps() {
r.register(tm);
}
r
}
}
impl Default for Registry {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builtin_contains_versions() {
let r = Registry::builtin();
assert!(r.supports(&Version(0, 0)));
}
#[test]
fn negotiate_finds_highest() {
let mut r = Registry::new();
r.register(TypeMap::new(Version(0, 0)));
r.register(TypeMap::new(Version(1, 0)));
r.register(TypeMap::new(Version(2, 0)));
let client = &[Version(0, 0)];
assert_eq!(r.negotiate(client), Some(Version(0, 0)));
let client = &[Version(1, 0), Version(0, 0)];
assert_eq!(r.negotiate(client), Some(Version(1, 0)));
let client = &[Version(5, 0)];
assert_eq!(r.negotiate(client), None);
}
#[test]
fn latest_returns_highest() {
let mut r = Registry::new();
r.register(TypeMap::new(Version(0, 0)));
r.register(TypeMap::new(Version(2, 0)));
r.register(TypeMap::new(Version(1, 0)));
assert_eq!(r.latest().unwrap().version, Version(2, 0));
}
}
}