use core::ffi::CStr;
use core::marker::PhantomData;
use crate::{GameSchemaVersion, SdkValue, ValueRef, ValueType, sys};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GameSchemaAvailability {
ets2: Option<GameSchemaVersion>,
ats: Option<GameSchemaVersion>,
}
impl GameSchemaAvailability {
#[must_use]
pub const fn new(ets2: Option<GameSchemaVersion>, ats: Option<GameSchemaVersion>) -> Self {
Self { ets2, ats }
}
#[must_use]
pub const fn available_since_ets2(self) -> Option<GameSchemaVersion> {
self.ets2
}
#[must_use]
pub const fn available_since_ats(self) -> Option<GameSchemaVersion> {
self.ats
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ConfigurationId {
name: &'static CStr,
availability: GameSchemaAvailability,
}
impl ConfigurationId {
#[must_use]
pub const fn new(name: &'static CStr, availability: GameSchemaAvailability) -> Self {
Self { name, availability }
}
#[must_use]
pub const fn name(self) -> &'static CStr {
self.name
}
#[must_use]
pub const fn availability(self) -> GameSchemaAvailability {
self.availability
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GameplayEventId {
name: &'static CStr,
availability: GameSchemaAvailability,
}
impl GameplayEventId {
#[must_use]
pub const fn new(name: &'static CStr, availability: GameSchemaAvailability) -> Self {
Self { name, availability }
}
#[must_use]
pub const fn name(self) -> &'static CStr {
self.name
}
#[must_use]
pub const fn availability(self) -> GameSchemaAvailability {
self.availability
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct Attribute<T: SdkValue> {
name: &'static CStr,
indexed: bool,
availability: GameSchemaAvailability,
marker: PhantomData<fn() -> T>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AnyAttribute {
name: &'static CStr,
value_type: ValueType,
indexed: bool,
availability: GameSchemaAvailability,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ConfigurationAttributeAssociation {
configuration: ConfigurationId,
attribute: AnyAttribute,
availability: GameSchemaAvailability,
}
impl ConfigurationAttributeAssociation {
#[must_use]
pub const fn new<T: SdkValue>(
configuration: ConfigurationId,
attribute: Attribute<T>,
availability: GameSchemaAvailability,
) -> Self {
Self {
configuration,
attribute: attribute.erase(),
availability,
}
}
#[must_use]
pub const fn configuration(self) -> ConfigurationId {
self.configuration
}
#[must_use]
pub const fn attribute(self) -> AnyAttribute {
self.attribute
}
#[must_use]
pub const fn availability(self) -> GameSchemaAvailability {
self.availability
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GameplayAttributeAssociation {
event: GameplayEventId,
attribute: AnyAttribute,
availability: GameSchemaAvailability,
}
impl GameplayAttributeAssociation {
#[must_use]
pub const fn new<T: SdkValue>(
event: GameplayEventId,
attribute: Attribute<T>,
availability: GameSchemaAvailability,
) -> Self {
Self {
event,
attribute: attribute.erase(),
availability,
}
}
#[must_use]
pub const fn event(self) -> GameplayEventId {
self.event
}
#[must_use]
pub const fn attribute(self) -> AnyAttribute {
self.attribute
}
#[must_use]
pub const fn availability(self) -> GameSchemaAvailability {
self.availability
}
}
impl AnyAttribute {
#[must_use]
pub const fn name(self) -> &'static CStr {
self.name
}
#[must_use]
pub const fn value_type(self) -> ValueType {
self.value_type
}
#[must_use]
pub const fn is_indexed(self) -> bool {
self.indexed
}
#[must_use]
pub const fn availability(self) -> GameSchemaAvailability {
self.availability
}
}
impl<T: SdkValue> Clone for Attribute<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T: SdkValue> Copy for Attribute<T> {}
impl<T: SdkValue> Attribute<T> {
#[must_use]
pub const fn new(name: &'static CStr, availability: GameSchemaAvailability) -> Self {
Self {
name,
indexed: false,
availability,
marker: PhantomData,
}
}
#[must_use]
pub const fn indexed(name: &'static CStr, availability: GameSchemaAvailability) -> Self {
Self {
name,
indexed: true,
availability,
marker: PhantomData,
}
}
#[must_use]
pub const fn name(self) -> &'static CStr {
self.name
}
#[must_use]
pub const fn is_indexed(self) -> bool {
self.indexed
}
#[must_use]
pub const fn availability(self) -> GameSchemaAvailability {
self.availability
}
#[must_use]
pub const fn value_type(self) -> sys::ScsValueType {
T::TYPE
}
#[must_use]
pub const fn erase(self) -> AnyAttribute {
AnyAttribute {
name: self.name,
value_type: T::VALUE_TYPE,
indexed: self.indexed,
availability: self.availability,
}
}
#[must_use]
pub fn decode(self, value: ValueRef<'_>) -> Option<T::Decoded<'_>> {
T::decode(value)
}
}