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

5
protocol/src/color.rs

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

11
protocol/src/cursor.rs

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

32
protocol/src/filter.rs

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

11
protocol/src/game.rs

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

9
protocol/src/lib.rs

@ -6,6 +6,11 @@ @@ -6,6 +6,11 @@
//! 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]
extern crate log;
@ -20,7 +25,7 @@ pub mod master; @@ -20,7 +25,7 @@ pub mod master;
pub mod server;
pub mod wrappers;
use std::fmt;
use core::fmt;
pub use cursor::CursorError;
pub use server_info::ServerInfo;
@ -76,7 +81,7 @@ impl fmt::Display for Error { @@ -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 {
fn from(source: CursorError) -> Self {

4
protocol/src/master.rs

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
//! 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::Error;
@ -143,7 +143,7 @@ impl<'a> QueryServersResponse<&'a [u8]> { @@ -143,7 +143,7 @@ impl<'a> QueryServersResponse<&'a [u8]> {
A: ServerAddress,
{
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]) {
// skip last address with port 0
return None;

2
protocol/src/server.rs

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

26
protocol/src/server_info.rs

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

6
protocol/src/wrappers.rs

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

Loading…
Cancel
Save