#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
pub enum PropertyValue {
Value {
value: fastn_type::Value,
is_mutable: bool,
line_number: usize,
},
Reference {
name: String,
kind: fastn_type::KindData,
source: fastn_type::PropertyValueSource,
is_mutable: bool,
line_number: usize,
},
Clone {
name: String,
kind: fastn_type::KindData,
source: fastn_type::PropertyValueSource,
is_mutable: bool,
line_number: usize,
},
FunctionCall(fastn_type::FunctionCall),
}
impl PropertyValue {
pub fn line_number(&self) -> usize {
match self {
PropertyValue::Value { line_number, .. }
| PropertyValue::Reference { line_number, .. }
| PropertyValue::Clone { line_number, .. }
| PropertyValue::FunctionCall(fastn_type::FunctionCall { line_number, .. }) => {
*line_number
}
}
}
pub fn is_mutable(&self) -> bool {
match self {
PropertyValue::Value { is_mutable, .. }
| PropertyValue::Reference { is_mutable, .. }
| PropertyValue::Clone { is_mutable, .. }
| PropertyValue::FunctionCall(fastn_type::FunctionCall { is_mutable, .. }) => {
*is_mutable
}
}
}
pub fn get_reference_or_clone(&self) -> Option<&String> {
match self {
PropertyValue::Reference { name, .. } | PropertyValue::Clone { name, .. } => Some(name),
_ => None,
}
}
pub fn reference_name(&self) -> Option<&String> {
match self {
PropertyValue::Reference { name, .. } => Some(name),
_ => None,
}
}
pub fn kind(&self) -> fastn_type::Kind {
match self {
PropertyValue::Value { value, .. } => value.kind(),
PropertyValue::Reference { kind, .. } => kind.kind.to_owned(),
PropertyValue::Clone { kind, .. } => kind.kind.to_owned(),
PropertyValue::FunctionCall(fastn_type::FunctionCall { kind, .. }) => {
kind.kind.to_owned()
}
}
}
pub fn set_reference_or_clone(&mut self, new_name: &str) {
match self {
PropertyValue::Reference { name, .. } | PropertyValue::Clone { name, .. } => {
*name = new_name.to_string();
}
_ => {}
}
}
pub fn is_value(&self) -> bool {
matches!(self, fastn_type::PropertyValue::Value { .. })
}
pub fn is_clone(&self) -> bool {
matches!(self, fastn_type::PropertyValue::Clone { .. })
}
pub fn get_function(&self) -> Option<&fastn_type::FunctionCall> {
match self {
PropertyValue::FunctionCall(f) => Some(f),
_ => None,
}
}
pub fn new_none(kind: fastn_type::KindData, line_number: usize) -> fastn_type::PropertyValue {
fastn_type::PropertyValue::Value {
value: fastn_type::Value::new_none(kind),
is_mutable: false,
line_number,
}
}
pub fn set_mutable(&mut self, mutable: bool) {
match self {
PropertyValue::Value { is_mutable, .. }
| PropertyValue::Reference { is_mutable, .. }
| PropertyValue::Clone { is_mutable, .. }
| PropertyValue::FunctionCall(fastn_type::FunctionCall { is_mutable, .. }) => {
*is_mutable = mutable;
}
}
}
}
#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
pub enum PropertyValueSource {
Global,
Local(String),
Loop(String),
}
impl PropertyValueSource {
pub fn is_global(&self) -> bool {
PropertyValueSource::Global.eq(self)
}
pub fn is_local(&self, name: &str) -> bool {
matches!(self, PropertyValueSource::Local(l_name) if l_name.eq(name))
}
pub fn get_name(&self) -> Option<String> {
match self {
PropertyValueSource::Local(s) | PropertyValueSource::Loop(s) => Some(s.to_owned()),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
pub enum Value {
String {
text: String,
},
Integer {
value: i64,
},
Decimal {
value: f64,
},
Boolean {
value: bool,
},
Object {
values: fastn_type::Map<PropertyValue>,
},
Record {
name: String,
fields: fastn_type::Map<PropertyValue>,
},
KwArgs {
arguments: fastn_type::Map<PropertyValue>,
},
OrType {
name: String,
variant: String,
full_variant: String,
value: Box<PropertyValue>, },
List {
data: Vec<PropertyValue>,
kind: fastn_type::KindData,
},
Optional {
data: Box<Option<Value>>,
kind: fastn_type::KindData,
},
UI {
name: String,
kind: fastn_type::KindData,
component: fastn_type::ComponentInvocation,
},
Module {
name: String,
things: fastn_type::Map<fastn_type::ModuleThing>,
},
}
impl Value {
pub fn new_none(kind: fastn_type::KindData) -> fastn_type::Value {
fastn_type::Value::Optional {
data: Box::new(None),
kind,
}
}
pub fn new_string(text: &str) -> fastn_type::Value {
fastn_type::Value::String {
text: text.to_string(),
}
}
pub fn new_or_type(
name: &str,
variant: &str,
full_variant: &str,
value: fastn_type::PropertyValue,
) -> fastn_type::Value {
fastn_type::Value::OrType {
name: name.to_string(),
variant: variant.to_string(),
full_variant: full_variant.to_string(),
value: Box::new(value),
}
}
pub fn inner(&self) -> Option<Self> {
match self {
Value::Optional { data, .. } => data.as_ref().to_owned(),
t => Some(t.to_owned()),
}
}
pub fn into_property_value(self, is_mutable: bool, line_number: usize) -> PropertyValue {
PropertyValue::Value {
value: self,
is_mutable,
line_number,
}
}
pub fn kind(&self) -> fastn_type::Kind {
match self {
Value::String { .. } => fastn_type::Kind::string(),
Value::Integer { .. } => fastn_type::Kind::integer(),
Value::Decimal { .. } => fastn_type::Kind::decimal(),
Value::Boolean { .. } => fastn_type::Kind::boolean(),
Value::Object { .. } => fastn_type::Kind::object(),
Value::Record { name, .. } => fastn_type::Kind::record(name),
Value::KwArgs { .. } => fastn_type::Kind::kwargs(),
Value::List { kind, .. } => kind.kind.clone().into_list(),
Value::Optional { kind, .. } => fastn_type::Kind::Optional {
kind: Box::new(kind.kind.clone()),
},
Value::UI { name, .. } => fastn_type::Kind::ui_with_name(name),
Value::OrType {
name,
variant,
full_variant,
..
} => fastn_type::Kind::or_type_with_variant(name, variant, full_variant),
Value::Module { .. } => fastn_type::Kind::module(),
}
}
pub fn is_record(&self, rec_name: &str) -> bool {
matches!(self, Self::Record { name, .. } if rec_name.eq(name))
}
pub fn is_or_type_variant(&self, or_variant: &str) -> bool {
matches!(self, Self::OrType { variant, .. } if or_variant.eq(variant))
}
pub fn ref_inner(&self) -> Option<&Self> {
match self {
Value::Optional { data, .. } => data.as_ref().as_ref(),
t => Some(t),
}
}
pub fn module_name_optional(&self) -> Option<String> {
match self {
fastn_type::Value::Module { name, .. } => Some(name.to_string()),
_ => None,
}
}
pub fn mut_module_optional(
&mut self,
) -> Option<(&str, &mut fastn_type::Map<fastn_type::ModuleThing>)> {
match self {
fastn_type::Value::Module { name, things } => Some((name, things)),
_ => None,
}
}
pub fn is_null(&self) -> bool {
if let Self::String { text, .. } = self {
return text.is_empty();
}
if let Self::Optional { data, .. } = self {
let value = if let Some(fastn_type::Value::String { text, .. }) = data.as_ref() {
text.is_empty()
} else {
false
};
if data.as_ref().eq(&None) || value {
return true;
}
}
false
}
pub fn is_empty(&self) -> bool {
if let Self::List { data, .. } = self {
if data.is_empty() {
return true;
}
}
false
}
pub fn is_equal(&self, other: &Self) -> bool {
match (self.to_owned().inner(), other.to_owned().inner()) {
(Some(Value::String { text: ref a, .. }), Some(Value::String { text: ref b, .. })) => {
a == b
}
(a, b) => a == b,
}
}
}