#![allow(clippy::new_without_default)]
use std::{
borrow::Cow,
collections::{HashMap, HashSet},
};
use rbx_types::{Variant, VariantType};
use serde::{Deserialize, Serialize};
use crate::{ClassTag, PropertyTag};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
#[non_exhaustive]
pub struct ReflectionDatabase<'a> {
pub version: [u32; 4],
#[serde(serialize_with = "crate::serde_util::ordered_map")]
pub classes: HashMap<Cow<'a, str>, ClassDescriptor<'a>>,
#[serde(default, serialize_with = "crate::serde_util::ordered_map")]
pub enums: HashMap<Cow<'a, str>, EnumDescriptor<'a>>,
}
impl<'a> ReflectionDatabase<'a> {
pub fn new() -> Self {
Self {
version: [0, 0, 0, 0],
classes: HashMap::new(),
enums: HashMap::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
#[non_exhaustive]
pub struct ClassDescriptor<'a> {
pub name: Cow<'a, str>,
#[serde(serialize_with = "crate::serde_util::ordered_set")]
pub tags: HashSet<ClassTag>,
#[serde(default)]
pub superclass: Option<Cow<'a, str>>,
#[serde(serialize_with = "crate::serde_util::ordered_map")]
pub properties: HashMap<Cow<'a, str>, PropertyDescriptor<'a>>,
#[serde(serialize_with = "crate::serde_util::ordered_map")]
pub default_properties: HashMap<Cow<'a, str>, Variant>,
}
impl<'a> ClassDescriptor<'a> {
pub fn new<S: Into<Cow<'a, str>>>(name: S) -> Self {
Self {
name: name.into(),
tags: HashSet::new(),
superclass: None,
properties: HashMap::new(),
default_properties: HashMap::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
#[non_exhaustive]
pub struct PropertyDescriptor<'a> {
pub name: Cow<'a, str>,
pub scriptability: Scriptability,
pub data_type: DataType<'a>,
#[serde(serialize_with = "crate::serde_util::ordered_set")]
pub tags: HashSet<PropertyTag>,
pub kind: PropertyKind<'a>,
}
impl<'a> PropertyDescriptor<'a> {
pub fn new<S: Into<Cow<'a, str>>>(name: S, data_type: DataType<'a>) -> Self {
Self {
name: name.into(),
scriptability: Scriptability::None,
data_type,
tags: HashSet::new(),
kind: PropertyKind::Canonical {
serialization: PropertySerialization::Serializes,
},
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum PropertyKind<'a> {
#[serde(rename_all = "PascalCase")]
Canonical {
serialization: PropertySerialization<'a>,
},
#[serde(rename_all = "PascalCase")]
Alias { alias_for: Cow<'a, str> },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum PropertySerialization<'a> {
Serializes,
DoesNotSerialize,
SerializesAs(Cow<'a, str>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub enum DataType<'a> {
Value(VariantType),
Enum(Cow<'a, str>),
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Scriptability {
None,
ReadWrite,
Read,
Write,
Custom,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct EnumDescriptor<'a> {
pub name: Cow<'a, str>,
#[serde(serialize_with = "crate::serde_util::ordered_map")]
pub items: HashMap<Cow<'a, str>, u32>,
}
impl<'a> EnumDescriptor<'a> {
pub fn new<S: Into<Cow<'a, str>>>(name: S) -> Self {
Self {
name: name.into(),
items: HashMap::new(),
}
}
}