Browse Source

protocol: add std and alloc features

master
Denis Drakhnia 3 weeks ago
parent
commit
3145e8bfc3
  1. 5
      protocol/Cargo.toml
  2. 5
      protocol/src/color.rs
  3. 11
      protocol/src/cursor.rs
  4. 32
      protocol/src/filter.rs
  5. 11
      protocol/src/game.rs
  6. 9
      protocol/src/lib.rs
  7. 4
      protocol/src/master.rs
  8. 2
      protocol/src/server.rs
  9. 26
      protocol/src/server_info.rs
  10. 6
      protocol/src/wrappers.rs

5
protocol/Cargo.toml

@ -11,6 +11,11 @@ rust-version = "1.56"
homepage = "https://xash.su" homepage = "https://xash.su"
repository = "https://git.mentality.rip/numas13/xash3d-master" repository = "https://git.mentality.rip/numas13/xash3d-master"
[features]
default = ["std"]
std = ["alloc"]
alloc = []
[dependencies] [dependencies]
log = "0.4.18" log = "0.4.18"
bitflags = "2.4" bitflags = "2.4"

5
protocol/src/color.rs

@ -3,7 +3,8 @@
//! Color codes for strings. //! Color codes for strings.
use std::borrow::Cow; #[cfg(feature = "alloc")]
use alloc::{borrow::Cow, string::String};
/// Color codes `^digit`. /// Color codes `^digit`.
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@ -131,6 +132,7 @@ impl<'a> Iterator for ColorIter<'a> {
/// # use xash3d_protocol::color::trim_color; /// # use xash3d_protocol::color::trim_color;
/// assert_eq!(trim_color("^1no^7 ^2colors^7"), "no colors"); /// assert_eq!(trim_color("^1no^7 ^2colors^7"), "no colors");
/// ``` /// ```
#[cfg(feature = "alloc")]
pub fn trim_color(s: &str) -> Cow<'_, str> { pub fn trim_color(s: &str) -> Cow<'_, str> {
let (_, s) = trim_start_color(s); let (_, s) = trim_start_color(s);
if !s.chars().any(|c| c == '^') { if !s.chars().any(|c| c == '^') {
@ -157,6 +159,7 @@ mod tests {
assert_eq!(trim_start_color("^1^2^3foo^2bar"), ("^3", "foo^2bar")); assert_eq!(trim_start_color("^1^2^3foo^2bar"), ("^3", "foo^2bar"));
} }
#[cfg(feature = "alloc")]
#[test] #[test]
fn trim_colors() { fn trim_colors() {
assert_eq!(trim_color("foo^2bar"), "foobar"); assert_eq!(trim_color("foo^2bar"), "foobar");

11
protocol/src/cursor.rs

@ -1,11 +1,14 @@
// SPDX-License-Identifier: LGPL-3.0-only // SPDX-License-Identifier: LGPL-3.0-only
// SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com> // SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com>
use std::{ use core::{
fmt::{self, Write}, fmt::{self, Write},
mem, str, mem, str,
}; };
#[cfg(feature = "alloc")]
use alloc::{borrow::ToOwned, boxed::Box, string::String};
use super::color; use super::color;
use super::wrappers::Str; use super::wrappers::Str;
@ -49,9 +52,9 @@ impl fmt::Display for CursorError {
} }
} }
impl std::error::Error for CursorError {} impl core::error::Error for CursorError {}
pub type Result<T, E = CursorError> = std::result::Result<T, E>; pub type Result<T, E = CursorError> = core::result::Result<T, E>;
pub trait GetKeyValue<'a>: Sized { pub trait GetKeyValue<'a>: Sized {
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self>; fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self>;
@ -76,6 +79,7 @@ impl<'a> GetKeyValue<'a> for &'a str {
} }
} }
#[cfg(feature = "alloc")]
impl<'a> GetKeyValue<'a> for Box<str> { impl<'a> GetKeyValue<'a> for Box<str> {
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> {
let raw = cur.get_key_value_raw()?; let raw = cur.get_key_value_raw()?;
@ -85,6 +89,7 @@ impl<'a> GetKeyValue<'a> for Box<str> {
} }
} }
#[cfg(feature = "alloc")]
impl<'a> GetKeyValue<'a> for String { impl<'a> GetKeyValue<'a> for String {
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> {
let raw = cur.get_key_value_raw()?; let raw = cur.get_key_value_raw()?;

32
protocol/src/filter.rs

@ -29,16 +29,16 @@
//! * Do not have bots //! * Do not have bots
//! * Is not protected by a password //! * Is not protected by a password
use std::fmt; use core::{fmt, net::SocketAddr, str::FromStr};
use std::net::SocketAddr;
use std::str::FromStr;
use bitflags::bitflags; use bitflags::bitflags;
use crate::cursor::{Cursor, GetKeyValue, PutKeyValue}; use crate::{
use crate::server::{ServerAdd, ServerFlags, ServerType}; cursor::{Cursor, GetKeyValue, PutKeyValue},
use crate::wrappers::Str; server::{ServerAdd, ServerFlags, ServerType},
use crate::{CursorError, Error, ServerInfo}; wrappers::Str,
ServerInfo, {CursorError, Error},
};
bitflags! { bitflags! {
/// Additional filter flags. /// Additional filter flags.
@ -196,11 +196,14 @@ impl Filter<'_> {
} }
/// Returns `true` if a server matches the filter. /// Returns `true` if a server matches the filter.
pub fn matches(&self, _addr: SocketAddr, info: &ServerInfo) -> bool { pub fn matches<T>(&self, _addr: SocketAddr, info: &ServerInfo<T>) -> bool
where
T: AsRef<[u8]>,
{
// TODO: match addr // TODO: match addr
!((info.flags & self.flags_mask) != self.flags !((info.flags & self.flags_mask) != self.flags
|| self.gamedir.map_or(false, |s| *s != &*info.gamedir) || self.gamedir.map_or(false, |s| *s != info.gamedir.as_ref())
|| self.map.map_or(false, |s| *s != &*info.map) || self.map.map_or(false, |s| *s != info.map.as_ref())
|| self.protocol.map_or(false, |s| s != info.protocol)) || self.protocol.map_or(false, |s| s != info.protocol))
} }
} }
@ -306,11 +309,14 @@ impl fmt::Display for &Filter<'_> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use crate::cursor::CursorMut;
use crate::wrappers::Str;
use std::net::SocketAddr; use std::net::SocketAddr;
use crate::{cursor::CursorMut, wrappers::Str};
use super::*;
type ServerInfo = crate::ServerInfo<Box<[u8]>>;
macro_rules! tests { macro_rules! tests {
($($name:ident$(($($predefined_f:ident: $predefined_v:expr),+ $(,)?))? { ($($name:ident$(($($predefined_f:ident: $predefined_v:expr),+ $(,)?))? {
$($src:expr => { $($src:expr => {

11
protocol/src/game.rs

@ -3,8 +3,7 @@
//! Game client packets. //! Game client packets.
use std::fmt; use core::{fmt, net::SocketAddr};
use std::net::SocketAddr;
use crate::cursor::{Cursor, CursorMut}; use crate::cursor::{Cursor, CursorMut};
use crate::filter::Filter; use crate::filter::Filter;
@ -129,10 +128,14 @@ impl<'a> Packet<'a> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::filter::{FilterFlags, Version};
use crate::wrappers::Str;
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
use crate::{
filter::{FilterFlags, Version},
wrappers::Str,
};
#[test] #[test]
fn query_servers() { fn query_servers() {
let p = QueryServers { let p = QueryServers {

9
protocol/src/lib.rs

@ -6,6 +6,11 @@
//! Xash3D protocol between clients, servers and masters. //! Xash3D protocol between clients, servers and masters.
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
@ -20,7 +25,7 @@ pub mod master;
pub mod server; pub mod server;
pub mod wrappers; pub mod wrappers;
use std::fmt; use core::fmt;
pub use cursor::CursorError; pub use cursor::CursorError;
pub use server_info::ServerInfo; pub use server_info::ServerInfo;
@ -76,7 +81,7 @@ impl fmt::Display for Error {
} }
} }
impl std::error::Error for Error {} impl core::error::Error for Error {}
impl From<CursorError> for Error { impl From<CursorError> for Error {
fn from(source: CursorError) -> Self { fn from(source: CursorError) -> Self {

4
protocol/src/master.rs

@ -3,7 +3,7 @@
//! Master server packets. //! Master server packets.
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use core::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use super::cursor::{Cursor, CursorMut}; use super::cursor::{Cursor, CursorMut};
use super::Error; use super::Error;
@ -143,7 +143,7 @@ impl<'a> QueryServersResponse<&'a [u8]> {
A: ServerAddress, A: ServerAddress,
{ {
let mut cur = Cursor::new(self.inner); let mut cur = Cursor::new(self.inner);
std::iter::from_fn(move || { core::iter::from_fn(move || {
if cur.remaining() == A::size() && cur.end().ends_with(&[0; 2]) { if cur.remaining() == A::size() && cur.end().ends_with(&[0; 2]) {
// skip last address with port 0 // skip last address with port 0
return None; return None;

2
protocol/src/server.rs

@ -3,7 +3,7 @@
//! Game server packets. //! Game server packets.
use std::fmt; use core::fmt;
use bitflags::bitflags; use bitflags::bitflags;

26
protocol/src/server_info.rs

@ -1,28 +1,46 @@
// SPDX-License-Identifier: LGPL-3.0-only // SPDX-License-Identifier: LGPL-3.0-only
// SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com> // SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com>
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
use super::filter::{FilterFlags, Version}; use super::filter::{FilterFlags, Version};
use super::server::{Region, ServerAdd}; use super::server::{Region, ServerAdd};
use super::wrappers::Str; use super::wrappers::Str;
/// Game server information. /// Game server information.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ServerInfo { pub struct ServerInfo<T> {
/// Server version. /// Server version.
pub version: Version, pub version: Version,
/// Server protocol version. /// Server protocol version.
pub protocol: u8, pub protocol: u8,
/// Server midification. /// Server midification.
pub gamedir: Box<[u8]>, pub gamedir: T,
/// Server map. /// Server map.
pub map: Box<[u8]>, pub map: T,
/// Server additional filter flags. /// Server additional filter flags.
pub flags: FilterFlags, pub flags: FilterFlags,
/// Server region. /// Server region.
pub region: Region, pub region: Region,
} }
impl ServerInfo { impl<'a> ServerInfo<&'a [u8]> {
/// Creates a new `ServerInfo`.
pub fn new(info: &ServerAdd<Str<&'a [u8]>>) -> Self {
Self {
version: info.version,
protocol: info.protocol,
gamedir: &info.gamedir,
map: &info.map,
flags: FilterFlags::from(info),
region: info.region,
}
}
}
#[cfg(any(feature = "alloc", test))]
impl ServerInfo<Box<[u8]>> {
/// Creates a new `ServerInfo`. /// Creates a new `ServerInfo`.
pub fn new(info: &ServerAdd<Str<&[u8]>>) -> Self { pub fn new(info: &ServerAdd<Str<&[u8]>>) -> Self {
Self { Self {

6
protocol/src/wrappers.rs

@ -3,11 +3,9 @@
//! Wrappers for byte slices with pretty-printers. //! Wrappers for byte slices with pretty-printers.
use std::fmt; use core::{fmt, ops::Deref};
use std::ops::Deref;
use crate::cursor::{CursorMut, PutKeyValue}; use crate::cursor::{CursorError, CursorMut, PutKeyValue};
use crate::CursorError;
/// Wrapper for slice of bytes with printing the bytes as a string. /// Wrapper for slice of bytes with printing the bytes as a string.
/// ///

Loading…
Cancel
Save