typst_library/foundations/
none.rs1use std::fmt::{self, Debug, Formatter};
2
3use ecow::EcoString;
4use serde::{Serialize, Serializer};
5
6use crate::diag::HintedStrResult;
7use crate::foundations::{
8 cast, ty, CastInfo, FromValue, IntoValue, Reflect, Repr, Type, Value,
9};
10
11#[ty(cast, name = "none")]
24#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
25pub struct NoneValue;
26
27impl Reflect for NoneValue {
28 fn input() -> CastInfo {
29 CastInfo::Type(Type::of::<Self>())
30 }
31
32 fn output() -> CastInfo {
33 CastInfo::Type(Type::of::<Self>())
34 }
35
36 fn castable(value: &Value) -> bool {
37 matches!(value, Value::None)
38 }
39}
40
41impl IntoValue for NoneValue {
42 fn into_value(self) -> Value {
43 Value::None
44 }
45}
46
47impl FromValue for NoneValue {
48 fn from_value(value: Value) -> HintedStrResult<Self> {
49 match value {
50 Value::None => Ok(Self),
51 _ => Err(Self::error(&value)),
52 }
53 }
54}
55
56impl Debug for NoneValue {
57 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
58 f.pad("None")
59 }
60}
61
62impl Repr for NoneValue {
63 fn repr(&self) -> EcoString {
64 "none".into()
65 }
66}
67
68impl Serialize for NoneValue {
69 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70 where
71 S: Serializer,
72 {
73 serializer.serialize_none()
74 }
75}
76
77cast! {
78 (),
79 self => Value::None,
80 _: NoneValue => (),
81}
82
83impl<T: Reflect> Reflect for Option<T> {
84 fn input() -> CastInfo {
85 T::input() + NoneValue::input()
86 }
87
88 fn output() -> CastInfo {
89 T::output() + NoneValue::output()
90 }
91
92 fn castable(value: &Value) -> bool {
93 NoneValue::castable(value) || T::castable(value)
94 }
95}
96
97impl<T: IntoValue> IntoValue for Option<T> {
98 fn into_value(self) -> Value {
99 match self {
100 Some(v) => v.into_value(),
101 None => Value::None,
102 }
103 }
104}
105
106impl<T: FromValue> FromValue for Option<T> {
107 fn from_value(value: Value) -> HintedStrResult<Self> {
108 match value {
109 Value::None => Ok(None),
110 v if T::castable(&v) => Ok(Some(T::from_value(v)?)),
111 _ => Err(Self::error(&value)),
112 }
113 }
114}