1use crate::{CordisError, ErrorCode, Result};
4use std::any::{Any, type_name};
5use std::fmt::{self, Debug, Formatter};
6use std::sync::Arc;
7
8#[derive(Clone)]
13pub struct Value {
14 inner: Arc<dyn Any + Send + Sync>,
15 type_name: &'static str,
16}
17
18impl Value {
19 pub fn new<T>(value: T) -> Self
21 where
22 T: Any + Send + Sync,
23 {
24 Self {
25 inner: Arc::new(value),
26 type_name: type_name::<T>(),
27 }
28 }
29
30 pub fn from_arc<T>(value: Arc<T>) -> Self
32 where
33 T: Any + Send + Sync,
34 {
35 Self {
36 inner: value,
37 type_name: type_name::<T>(),
38 }
39 }
40
41 pub const fn type_name(&self) -> &'static str {
43 self.type_name
44 }
45
46 pub fn is<T: Any>(&self) -> bool {
48 self.inner.is::<T>()
49 }
50
51 pub fn downcast<T>(&self) -> Result<Arc<T>>
53 where
54 T: Any + Send + Sync,
55 {
56 self.inner.clone().downcast::<T>().map_err(|_| {
57 CordisError::with_message(
58 ErrorCode::TypeMismatch,
59 format!(
60 "expected value of type `{}`, found `{}`",
61 type_name::<T>(),
62 self.type_name
63 ),
64 )
65 })
66 }
67
68 pub fn as_any(&self) -> &(dyn Any + Send + Sync) {
70 self.inner.as_ref()
71 }
72
73 pub(crate) fn ptr_eq(&self, other: &Value) -> bool {
75 Arc::ptr_eq(&self.inner, &other.inner)
76 }
77}
78
79impl Default for Value {
80 fn default() -> Self {
81 Self::new(())
82 }
83}
84
85impl Debug for Value {
86 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
87 f.debug_struct("Value")
88 .field("type_name", &self.type_name)
89 .finish_non_exhaustive()
90 }
91}
92
93pub type Config = Value;