2025-01-15 03:52:32 +09:00
|
|
|
use std::{fmt::Debug, str::FromStr};
|
|
|
|
|
|
|
|
|
|
use smol_str::SmolStr;
|
|
|
|
|
|
2025-01-24 04:40:07 +09:00
|
|
|
use crate::token::{Token, TokenMatchResult};
|
2025-01-24 04:08:59 +09:00
|
|
|
|
2025-01-21 04:31:03 +09:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub enum ParameterValue {
|
2025-01-21 12:36:54 +09:00
|
|
|
OpaqueString(String),
|
2025-01-21 04:31:03 +09:00
|
|
|
MemberRef(String),
|
|
|
|
|
SystemRef(String),
|
|
|
|
|
MemberPrivacyTarget(String),
|
|
|
|
|
PrivacyLevel(String),
|
|
|
|
|
Toggle(bool),
|
|
|
|
|
}
|
2025-01-15 03:52:32 +09:00
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
|
|
|
|
pub struct Parameter {
|
|
|
|
|
name: SmolStr,
|
|
|
|
|
kind: ParameterKind,
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
impl Parameter {
|
|
|
|
|
pub fn name(&self) -> &str {
|
|
|
|
|
&self.name
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
pub fn kind(&self) -> ParameterKind {
|
|
|
|
|
self.kind
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
impl From<ParameterKind> for Parameter {
|
|
|
|
|
fn from(value: ParameterKind) -> Self {
|
|
|
|
|
Parameter {
|
|
|
|
|
name: value.default_name().into(),
|
|
|
|
|
kind: value,
|
|
|
|
|
}
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
2025-01-21 12:36:54 +09:00
|
|
|
}
|
2025-01-15 03:52:32 +09:00
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
impl From<(&str, ParameterKind)> for Parameter {
|
|
|
|
|
fn from((name, kind): (&str, ParameterKind)) -> Self {
|
|
|
|
|
Parameter {
|
|
|
|
|
name: name.into(),
|
|
|
|
|
kind,
|
|
|
|
|
}
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
2025-01-21 12:36:54 +09:00
|
|
|
}
|
2025-01-15 03:52:32 +09:00
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
|
pub enum ParameterKind {
|
|
|
|
|
OpaqueString,
|
|
|
|
|
OpaqueStringRemainder,
|
|
|
|
|
MemberRef,
|
|
|
|
|
SystemRef,
|
|
|
|
|
MemberPrivacyTarget,
|
|
|
|
|
PrivacyLevel,
|
|
|
|
|
Toggle,
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
impl ParameterKind {
|
|
|
|
|
pub(crate) fn default_name(&self) -> &str {
|
|
|
|
|
match self {
|
|
|
|
|
ParameterKind::OpaqueString => "string",
|
|
|
|
|
ParameterKind::OpaqueStringRemainder => "string",
|
|
|
|
|
ParameterKind::MemberRef => "target",
|
|
|
|
|
ParameterKind::SystemRef => "target",
|
|
|
|
|
ParameterKind::MemberPrivacyTarget => "member_privacy_target",
|
|
|
|
|
ParameterKind::PrivacyLevel => "privacy_level",
|
|
|
|
|
ParameterKind::Toggle => "toggle",
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-15 03:52:32 +09:00
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
pub(crate) fn remainder(&self) -> bool {
|
|
|
|
|
matches!(self, ParameterKind::OpaqueStringRemainder)
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
pub(crate) fn format(&self, f: &mut std::fmt::Formatter, param_name: &str) -> std::fmt::Result {
|
|
|
|
|
match self {
|
|
|
|
|
ParameterKind::OpaqueString | ParameterKind::OpaqueStringRemainder => {
|
|
|
|
|
write!(f, "[{param_name}]")
|
|
|
|
|
}
|
|
|
|
|
ParameterKind::MemberRef => write!(f, "<target member>"),
|
|
|
|
|
ParameterKind::SystemRef => write!(f, "<target system>"),
|
|
|
|
|
ParameterKind::MemberPrivacyTarget => write!(f, "<privacy target>"),
|
|
|
|
|
ParameterKind::PrivacyLevel => write!(f, "[privacy level]"),
|
|
|
|
|
ParameterKind::Toggle => write!(f, "on/off"),
|
|
|
|
|
}
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
pub(crate) fn match_value(&self, input: &str) -> Result<ParameterValue, SmolStr> {
|
|
|
|
|
match self {
|
|
|
|
|
ParameterKind::OpaqueString | ParameterKind::OpaqueStringRemainder => {
|
|
|
|
|
Ok(ParameterValue::OpaqueString(input.into()))
|
|
|
|
|
}
|
|
|
|
|
ParameterKind::MemberRef => Ok(ParameterValue::MemberRef(input.into())),
|
|
|
|
|
ParameterKind::SystemRef => Ok(ParameterValue::SystemRef(input.into())),
|
|
|
|
|
ParameterKind::MemberPrivacyTarget => MemberPrivacyTargetKind::from_str(input)
|
|
|
|
|
.map(|target| ParameterValue::MemberPrivacyTarget(target.as_ref().into())),
|
|
|
|
|
ParameterKind::PrivacyLevel => PrivacyLevelKind::from_str(input)
|
|
|
|
|
.map(|level| ParameterValue::PrivacyLevel(level.as_ref().into())),
|
|
|
|
|
ParameterKind::Toggle => {
|
|
|
|
|
Toggle::from_str(input).map(|t| ParameterValue::Toggle(t.into()))
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub enum MemberPrivacyTargetKind {
|
|
|
|
|
Visibility,
|
|
|
|
|
Name,
|
|
|
|
|
Description,
|
|
|
|
|
Banner,
|
|
|
|
|
Avatar,
|
|
|
|
|
Birthday,
|
|
|
|
|
Pronouns,
|
|
|
|
|
Proxy,
|
|
|
|
|
Metadata,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AsRef<str> for MemberPrivacyTargetKind {
|
|
|
|
|
fn as_ref(&self) -> &str {
|
|
|
|
|
match self {
|
|
|
|
|
Self::Visibility => "visibility",
|
|
|
|
|
Self::Name => "name",
|
|
|
|
|
Self::Description => "description",
|
|
|
|
|
Self::Banner => "banner",
|
|
|
|
|
Self::Avatar => "avatar",
|
|
|
|
|
Self::Birthday => "birthday",
|
|
|
|
|
Self::Pronouns => "pronouns",
|
|
|
|
|
Self::Proxy => "proxy",
|
|
|
|
|
Self::Metadata => "metadata",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl FromStr for MemberPrivacyTargetKind {
|
|
|
|
|
// todo: figure out how to represent these errors best
|
|
|
|
|
type Err = SmolStr;
|
|
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
|
// todo: this doesnt parse all the possible ways
|
|
|
|
|
match s.to_lowercase().as_str() {
|
|
|
|
|
"visibility" => Ok(Self::Visibility),
|
|
|
|
|
"name" => Ok(Self::Name),
|
|
|
|
|
"description" => Ok(Self::Description),
|
|
|
|
|
"banner" => Ok(Self::Banner),
|
|
|
|
|
"avatar" => Ok(Self::Avatar),
|
|
|
|
|
"birthday" => Ok(Self::Birthday),
|
|
|
|
|
"pronouns" => Ok(Self::Pronouns),
|
|
|
|
|
"proxy" => Ok(Self::Proxy),
|
|
|
|
|
"metadata" => Ok(Self::Metadata),
|
|
|
|
|
_ => Err("invalid member privacy target".into()),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub enum PrivacyLevelKind {
|
|
|
|
|
Public,
|
|
|
|
|
Private,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AsRef<str> for PrivacyLevelKind {
|
|
|
|
|
fn as_ref(&self) -> &str {
|
|
|
|
|
match self {
|
|
|
|
|
Self::Public => "public",
|
|
|
|
|
Self::Private => "private",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl FromStr for PrivacyLevelKind {
|
|
|
|
|
type Err = SmolStr; // todo
|
|
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
|
match s {
|
|
|
|
|
"public" => Ok(PrivacyLevelKind::Public),
|
|
|
|
|
"private" => Ok(PrivacyLevelKind::Private),
|
|
|
|
|
_ => Err("invalid privacy level".into()),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 04:08:59 +09:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
|
2025-01-21 12:36:54 +09:00
|
|
|
pub enum Toggle {
|
|
|
|
|
On,
|
|
|
|
|
Off,
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
impl FromStr for Toggle {
|
2025-01-15 03:52:32 +09:00
|
|
|
type Err = SmolStr;
|
|
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
2025-01-24 04:40:07 +09:00
|
|
|
let matches_self = |toggle: &Self| {
|
|
|
|
|
matches!(
|
|
|
|
|
Token::from(*toggle).try_match(Some(s)),
|
|
|
|
|
Some(TokenMatchResult::MatchedValue)
|
|
|
|
|
)
|
|
|
|
|
};
|
2025-01-24 04:08:59 +09:00
|
|
|
[Self::On, Self::Off]
|
|
|
|
|
.into_iter()
|
|
|
|
|
.find(matches_self)
|
|
|
|
|
.ok_or_else(|| SmolStr::new("invalid toggle, must be on/off"))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<Toggle> for Token {
|
|
|
|
|
fn from(toggle: Toggle) -> Self {
|
|
|
|
|
match toggle {
|
|
|
|
|
Toggle::On => Self::from(("on", ["yes", "true", "enable", "enabled"])),
|
|
|
|
|
Toggle::Off => Self::from(("off", ["no", "false", "disable", "disabled"])),
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 12:36:54 +09:00
|
|
|
impl Into<bool> for Toggle {
|
2025-01-15 03:52:32 +09:00
|
|
|
fn into(self) -> bool {
|
2025-01-21 12:36:54 +09:00
|
|
|
match self {
|
|
|
|
|
Toggle::On => true,
|
|
|
|
|
Toggle::Off => false,
|
2025-01-15 03:52:32 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|