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