Skip to content

Instantly share code, notes, and snippets.

@theangryangel
Created September 10, 2023 20:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theangryangel/a905f7a49732f52c916180d0922a6b6c to your computer and use it in GitHub Desktop.
Save theangryangel/a905f7a49732f52c916180d0922a6b6c to your computer and use it in GitHub Desktop.
use core::fmt::Debug;
use std::marker::PhantomData;
#[derive(Debug)]
pub enum Mode {
Uncompressed,
Compressed,
}
pub trait VersionedPacket: Debug {
fn read(id: usize) -> Self;
const VERSION: u8 = 0;
const DEFAULT_MODE: Mode = Mode::Compressed;
}
pub mod v1 {
use super::Mode;
#[derive(Debug)]
pub enum Packet {
One,
Two,
Other,
}
impl super::VersionedPacket for Packet {
fn read(id: usize) -> Self {
match id {
1 => Self::One,
2 => Self::Two,
_ => Self::Other
}
}
const VERSION: u8 = 1;
const DEFAULT_MODE: Mode = Mode::Uncompressed;
}
}
pub mod v2 {
pub use super::v1::*;
#[derive(Debug)]
pub enum Packet {
Three,
Four,
}
impl super::VersionedPacket for Packet {
fn read(id: usize) -> Self {
match id {
1 => Self::Three,
_ => Self::Four
}
}
const VERSION: u8 = 2;
}
}
pub struct Codec<P: VersionedPacket> {
inner: CodecInner<P>,
}
impl<P: VersionedPacket> Codec<P> {
fn new() -> Self {
Self {
inner: CodecInner::<P>::new(),
}
}
pub fn read(&self, id: usize) -> P {
self.inner.read(id)
}
}
pub struct CodecInner<P: VersionedPacket> {
phantom: PhantomData<P>,
}
impl<P: VersionedPacket> CodecInner<P> {
pub fn new() -> Self {
Self {
phantom: PhantomData,
}
}
pub fn read(&self, id: usize) -> P {
P::read(id)
}
}
pub struct Connection<P: VersionedPacket> {
codec: Codec<P>
}
impl<P: VersionedPacket> Connection<P> {
pub fn new() -> Self {
Self { codec: Codec::<P>::new() }
}
pub fn read(&self, id: usize) -> P {
self.codec.read(id)
}
pub fn version(&self) -> usize {
P::VERSION.into()
}
pub fn default_mode(&self) -> Mode {
P::DEFAULT_MODE
}
}
fn main() {
let c = Connection::<v1::Packet>::new();
println!("Hello, world! version={:?} packet={:?}, mode={:?}", c.version(), c.read(2), c.default_mode());
let c = Connection::<v2::Packet>::new();
println!("Hello, world! version={:?} packet={:?}, mode={:?}", c.version(), c.read(2), c.default_mode());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment