openusd-rs 0.1.0

Work in progress, opinionated implementation of OpenUSD in pure Rust
Documentation
//! Value Types

use super::*;
use half::f16;
use std::collections::HashMap;

pub type Array<T> = Vec<T>;
pub type Dictionary = HashMap<String, vt::Value>;

#[derive(Debug, Clone)]
pub struct Value {
	store: ValueStore,
}

impl Value {
	pub fn get_unchecked<T: ValueType>(&self) -> T {
		T::load(&self.store).unwrap()
	}

	pub fn get<T: ValueType>(&self) -> Option<T> {
		T::load(&self.store)
	}

	pub fn new<T: ValueType>(value: T) -> Self {
		Value {
			store: value.store(),
		}
	}

	pub fn empty() -> Self {
		Value {
			store: ValueStore::Empty,
		}
	}

	pub fn is_empty(&self) -> bool {
		matches!(self.store, ValueStore::Empty)
	}
}

#[derive(Debug, Clone)]
pub enum ValueStore {
	Empty,

	Bool(bool),
	BoolArray(Array<bool>),

	UChar(u8),
	UCharArray(Array<u8>),

	IntArray(Array<i32>),
	UIntArray(Array<u32>),

	Int(i32),
	Half(f16),
	HalfArray(Array<f16>),
	Float(f32),
	FloatArray(Array<f32>),
	Double(f64),
	DoubleArray(Array<f64>),

	Vec2i(gf::Vec2i),
	Vec2h(gf::Vec2h),
	Vec2f(gf::Vec2f),
	Vec2fArray(Array<gf::Vec2f>),
	Vec2d(gf::Vec2d),

	Vec3i(gf::Vec3i),
	Vec3h(gf::Vec3h),
	Vec3f(gf::Vec3f),
	Vec3fArray(Array<gf::Vec3f>),
	Vec3d(gf::Vec3d),

	Vec4i(gf::Vec4i),
	Vec4h(gf::Vec4h),
	Vec4f(gf::Vec4f),
	Vec4fArray(Array<gf::Vec4f>),
	Vec4d(gf::Vec4d),

	Quath(gf::Quath),
	Quatf(gf::Quatf),
	Quatd(gf::Quatd),

	Matrix2d(gf::Matrix2d),
	Matrix3d(gf::Matrix3d),
	Matrix4d(gf::Matrix4d),

	Token(tf::Token),
	TokenArray(Array<tf::Token>),

	String(String),
	StringArray(Array<String>),

	IntListOp(sdf::IntListOp),
	UIntListOp(sdf::UIntListOp),
	Int64ListOp(sdf::Int64ListOp),
	UInt64ListOp(sdf::UInt64ListOp),

	TokenListOp(sdf::TokenListOp),
	StringListOp(sdf::StringListOp),
	PathListOp(sdf::PathListOp),
	ReferenceListOp(sdf::ReferenceListOp),
	PayloadListOp(sdf::PayloadListOp),

	Path(sdf::Path),
	AssetPath(sdf::AssetPath),

	Specifier(sdf::Specifier),
	Variability(sdf::Variability),

	Dictionary(Dictionary),
}

pub trait ValueType {
	fn load(store: &ValueStore) -> Option<Self>
	where
		Self: Sized;
	fn store(self) -> ValueStore;
}

macro_rules! impl_value_type_clone {
	($type:ty, $store:ident) => {
		impl ValueType for $type {
			fn load(store: &ValueStore) -> Option<Self> {
				match store {
					ValueStore::$store(v) => Some(v.clone()),
					_ => None,
				}
			}

			fn store(self) -> ValueStore {
				ValueStore::$store(self)
			}
		}

		impl From<$type> for Value {
			fn from(value: $type) -> Self {
				Value {
					store: ValueStore::$store(value),
				}
			}
		}
	};
}

macro_rules! impl_value_type_deref {
	($type:ty, $store:ident) => {
		impl ValueType for $type {
			fn load(store: &ValueStore) -> Option<Self> {
				match store {
					ValueStore::$store(v) => Some(*v),
					_ => None,
				}
			}

			fn store(self) -> ValueStore {
				ValueStore::$store(self)
			}
		}

		impl From<$type> for Value {
			fn from(value: $type) -> Self {
				Value {
					store: ValueStore::$store(value),
				}
			}
		}
	};
}

impl_value_type_deref!(bool, Bool);
impl_value_type_clone!(Array<bool>, BoolArray);

impl_value_type_deref!(u8, UChar);
impl_value_type_clone!(Array<u8>, UCharArray);

impl_value_type_clone!(Array<i32>, IntArray);
impl_value_type_clone!(Array<u32>, UIntArray);

impl_value_type_clone!(tf::Token, Token);
impl_value_type_clone!(Array<tf::Token>, TokenArray);

impl_value_type_clone!(String, String);
impl_value_type_clone!(Array<String>, StringArray);

impl_value_type_clone!(sdf::IntListOp, IntListOp);
impl_value_type_clone!(sdf::UIntListOp, UIntListOp);
impl_value_type_clone!(sdf::Int64ListOp, Int64ListOp);
impl_value_type_clone!(sdf::UInt64ListOp, UInt64ListOp);

impl_value_type_clone!(sdf::Path, Path);
impl_value_type_clone!(sdf::AssetPath, AssetPath);

impl_value_type_deref!(i32, Int);
impl_value_type_deref!(f16, Half);
impl_value_type_clone!(Array<f16>, HalfArray);
impl_value_type_deref!(f32, Float);
impl_value_type_clone!(Array<f32>, FloatArray);
impl_value_type_deref!(f64, Double);
impl_value_type_clone!(Array<f64>, DoubleArray);

impl_value_type_deref!(gf::Vec2i, Vec2i);
impl_value_type_deref!(gf::Vec2h, Vec2h);
impl_value_type_deref!(gf::Vec2f, Vec2f);
impl_value_type_clone!(Array<gf::Vec2f>, Vec2fArray);
impl_value_type_deref!(gf::Vec2d, Vec2d);

impl_value_type_deref!(gf::Vec3i, Vec3i);
impl_value_type_deref!(gf::Vec3h, Vec3h);
impl_value_type_deref!(gf::Vec3f, Vec3f);
impl_value_type_clone!(Array<gf::Vec3f>, Vec3fArray);
impl_value_type_deref!(gf::Vec3d, Vec3d);

impl_value_type_deref!(gf::Vec4i, Vec4i);
impl_value_type_deref!(gf::Vec4h, Vec4h);
impl_value_type_deref!(gf::Vec4f, Vec4f);
impl_value_type_clone!(Array<gf::Vec4f>, Vec4fArray);
impl_value_type_deref!(gf::Vec4d, Vec4d);

impl_value_type_deref!(gf::Quath, Quath);
impl_value_type_deref!(gf::Quatf, Quatf);
impl_value_type_deref!(gf::Quatd, Quatd);

impl_value_type_deref!(gf::Matrix2d, Matrix2d);
impl_value_type_deref!(gf::Matrix3d, Matrix3d);
impl_value_type_deref!(gf::Matrix4d, Matrix4d);

impl_value_type_deref!(sdf::Specifier, Specifier);
impl_value_type_deref!(sdf::Variability, Variability);

impl_value_type_clone!(Dictionary, Dictionary);

impl_value_type_clone!(sdf::PathListOp, PathListOp);