use crate::TypedValueHandle;
use crate::ValueHandle;
#[derive(Debug)]
pub enum Value {
Nil(NilValue),
Bool(BoolValue),
Fixnum(FixnumValue),
Symbol(SymbolValue),
Array(ArrayValue),
Hash(HashValue),
Object(ObjectValue),
String(StringValue),
UserDefined(UserDefinedValue),
}
impl Value {
pub fn as_symbol(&self) -> Option<&SymbolValue> {
match self {
Self::Symbol(value) => Some(value),
_ => None,
}
}
pub fn as_object(&self) -> Option<&ObjectValue> {
match self {
Self::Object(value) => Some(value),
_ => None,
}
}
pub fn as_string(&self) -> Option<&StringValue> {
match self {
Self::String(value) => Some(value),
_ => None,
}
}
pub fn kind(&self) -> ValueKind {
match self {
Self::Nil(_) => ValueKind::Nil,
Self::Bool(_) => ValueKind::Bool,
Self::Fixnum(_) => ValueKind::Fixnum,
Self::Symbol(_) => ValueKind::Symbol,
Self::Array(_) => ValueKind::Array,
Self::Hash(_) => ValueKind::Hash,
Self::Object(_) => ValueKind::Object,
Self::String(_) => ValueKind::String,
Self::UserDefined(_) => ValueKind::UserDefined,
}
}
}
impl From<NilValue> for Value {
fn from(value: NilValue) -> Self {
Self::Nil(value)
}
}
impl From<BoolValue> for Value {
fn from(value: BoolValue) -> Self {
Self::Bool(value)
}
}
impl From<FixnumValue> for Value {
fn from(value: FixnumValue) -> Self {
Self::Fixnum(value)
}
}
impl From<SymbolValue> for Value {
fn from(value: SymbolValue) -> Self {
Self::Symbol(value)
}
}
impl From<ArrayValue> for Value {
fn from(value: ArrayValue) -> Self {
Self::Array(value)
}
}
impl From<HashValue> for Value {
fn from(value: HashValue) -> Self {
Self::Hash(value)
}
}
impl From<ObjectValue> for Value {
fn from(value: ObjectValue) -> Self {
Self::Object(value)
}
}
impl From<StringValue> for Value {
fn from(value: StringValue) -> Self {
Self::String(value)
}
}
impl From<UserDefinedValue> for Value {
fn from(value: UserDefinedValue) -> Self {
Self::UserDefined(value)
}
}
#[derive(Debug)]
pub struct NilValue;
#[derive(Debug, Copy, Clone)]
pub struct BoolValue {
value: bool,
}
impl BoolValue {
pub(super) fn new(value: bool) -> Self {
Self { value }
}
pub fn value(self) -> bool {
self.value
}
}
#[derive(Debug, Copy, Clone)]
pub struct FixnumValue {
value: i32,
}
impl FixnumValue {
pub(super) fn new(value: i32) -> Self {
Self { value }
}
pub fn value(self) -> i32 {
self.value
}
}
#[derive(Debug)]
pub struct SymbolValue {
value: Vec<u8>,
}
impl SymbolValue {
pub(super) fn new(value: Vec<u8>) -> Self {
Self { value }
}
pub fn value(&self) -> &[u8] {
&self.value
}
}
#[derive(Debug)]
pub struct ArrayValue {
value: Vec<ValueHandle>,
}
impl ArrayValue {
pub(crate) fn new(value: Vec<ValueHandle>) -> Self {
Self { value }
}
pub fn value(&self) -> &[ValueHandle] {
&self.value
}
pub fn len(&self) -> usize {
self.value.len()
}
pub fn is_empty(&self) -> bool {
self.value.is_empty()
}
}
#[derive(Debug)]
pub struct HashValue {
value: Vec<(ValueHandle, ValueHandle)>,
default_value: Option<ValueHandle>,
}
impl HashValue {
pub(crate) fn new(
value: Vec<(ValueHandle, ValueHandle)>,
default_value: Option<ValueHandle>,
) -> Self {
Self {
value,
default_value,
}
}
pub fn value(&self) -> &[(ValueHandle, ValueHandle)] {
&self.value
}
pub fn default_value(&self) -> Option<ValueHandle> {
self.default_value
}
}
#[derive(Debug)]
pub struct ObjectValue {
name: TypedValueHandle<SymbolValue>,
instance_variables: Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>,
}
impl ObjectValue {
pub(crate) fn new(
name: TypedValueHandle<SymbolValue>,
instance_variables: Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>,
) -> Self {
Self {
name,
instance_variables,
}
}
pub fn name(&self) -> TypedValueHandle<SymbolValue> {
self.name
}
pub fn instance_variables(&self) -> &[(TypedValueHandle<SymbolValue>, ValueHandle)] {
&self.instance_variables
}
}
#[derive(Debug)]
pub struct StringValue {
value: Vec<u8>,
instance_variables: Option<Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>>,
}
impl StringValue {
pub(crate) fn new(value: Vec<u8>) -> Self {
Self {
value,
instance_variables: None,
}
}
pub fn value(&self) -> &[u8] {
&self.value
}
pub fn instance_variables(&self) -> Option<&[(TypedValueHandle<SymbolValue>, ValueHandle)]> {
self.instance_variables.as_deref()
}
pub(crate) fn set_instance_variables(
&mut self,
mut instance_variables: Option<Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>>,
) -> Option<Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>> {
std::mem::swap(&mut self.instance_variables, &mut instance_variables);
instance_variables
}
}
#[derive(Debug)]
pub struct UserDefinedValue {
name: TypedValueHandle<SymbolValue>,
value: Vec<u8>,
instance_variables: Option<Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>>,
}
impl UserDefinedValue {
pub(crate) fn new(name: TypedValueHandle<SymbolValue>, value: Vec<u8>) -> Self {
Self {
name,
value,
instance_variables: None,
}
}
pub fn name(&self) -> TypedValueHandle<SymbolValue> {
self.name
}
pub fn value(&self) -> &[u8] {
&self.value
}
pub fn instance_variables(&self) -> Option<&[(TypedValueHandle<SymbolValue>, ValueHandle)]> {
self.instance_variables.as_deref()
}
pub(crate) fn set_instance_variables(
&mut self,
mut instance_variables: Option<Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>>,
) -> Option<Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>> {
std::mem::swap(&mut self.instance_variables, &mut instance_variables);
instance_variables
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ValueKind {
Nil,
Bool,
Fixnum,
Symbol,
Array,
Hash,
Object,
String,
UserDefined,
}