script/dom/
quotaexceedederror.rs1use dom_struct::dom_struct;
6use js::context::JSContext;
7use js::gc::HandleObject;
8use rustc_hash::FxHashMap;
9use script_bindings::codegen::GenericBindings::QuotaExceededErrorBinding::{
10 QuotaExceededErrorMethods, QuotaExceededErrorOptions,
11};
12use script_bindings::num::Finite;
13use script_bindings::reflector::{reflect_dom_object, reflect_dom_object_with_proto};
14use script_bindings::root::DomRoot;
15use script_bindings::script_runtime::CanGc;
16use script_bindings::str::DOMString;
17use servo_base::id::{QuotaExceededErrorId, QuotaExceededErrorIndex};
18use servo_constellation_traits::SerializableQuotaExceededError;
19
20use crate::dom::bindings::error::Error;
21use crate::dom::bindings::serializable::Serializable;
22use crate::dom::bindings::structuredclone::StructuredData;
23use crate::dom::types::{DOMException, GlobalScope};
24
25#[dom_struct]
27pub(crate) struct QuotaExceededError {
28 dom_exception: DOMException,
30 quota: Option<Finite<f64>>,
32 requested: Option<Finite<f64>>,
34}
35
36impl QuotaExceededError {
37 fn new_inherited(
38 message: DOMString,
39 quota: Option<Finite<f64>>,
40 requested: Option<Finite<f64>>,
41 ) -> Self {
42 Self {
43 dom_exception: DOMException::new_inherited(message, "QuotaExceededError".into()),
44 quota,
45 requested,
46 }
47 }
48
49 pub(crate) fn new(
50 global: &GlobalScope,
51 message: DOMString,
52 quota: Option<Finite<f64>>,
53 requested: Option<Finite<f64>>,
54 can_gc: CanGc,
55 ) -> DomRoot<Self> {
56 reflect_dom_object(
57 Box::new(Self::new_inherited(message, quota, requested)),
58 global,
59 can_gc,
60 )
61 }
62}
63
64impl QuotaExceededErrorMethods<crate::DomTypeHolder> for QuotaExceededError {
65 fn Constructor(
67 global: &GlobalScope,
68 proto: Option<HandleObject>,
69 can_gc: CanGc,
70 message: DOMString,
71 options: &QuotaExceededErrorOptions,
72 ) -> Result<DomRoot<Self>, Error> {
73 if let Some(quota) = options.quota {
75 if *quota < 0.0 {
77 return Err(Error::Range(
78 c"quota must be at least zero if present".to_owned(),
79 ));
80 }
81 }
82 if let Some(requested) = options.requested {
84 if *requested < 0.0 {
86 return Err(Error::Range(
87 c"requested must be at least zero if present".to_owned(),
88 ));
89 }
90 }
91 if let (Some(quota), Some(requested)) = (options.quota, options.requested) &&
94 *requested < *quota
95 {
96 return Err(Error::Range(c"requested is less than quota".to_owned()));
97 }
98 Ok(reflect_dom_object_with_proto(
99 Box::new(QuotaExceededError::new_inherited(
100 message,
101 options.quota,
102 options.requested,
103 )),
104 global,
105 proto,
106 can_gc,
107 ))
108 }
109
110 fn GetQuota(&self) -> Option<Finite<f64>> {
112 self.quota
114 }
115
116 fn GetRequested(&self) -> Option<Finite<f64>> {
118 self.requested
120 }
121}
122
123impl Serializable for QuotaExceededError {
124 type Index = QuotaExceededErrorIndex;
125 type Data = SerializableQuotaExceededError;
126
127 fn serialize(&self) -> Result<(QuotaExceededErrorId, Self::Data), ()> {
129 let (_, dom_exception) = self.dom_exception.serialize()?;
130 let serialized = SerializableQuotaExceededError {
131 dom_exception,
132 quota: self.quota.as_deref().copied(),
133 requested: self.requested.as_deref().copied(),
134 };
135 Ok((QuotaExceededErrorId::new(), serialized))
136 }
137
138 fn deserialize(
140 cx: &mut JSContext,
141 owner: &GlobalScope,
142 serialized: Self::Data,
143 ) -> Result<DomRoot<Self>, ()>
144 where
145 Self: Sized,
146 {
147 Ok(Self::new(
148 owner,
149 DOMString::from(serialized.dom_exception.message),
150 serialized
151 .quota
152 .map(|val| Finite::new(val).ok_or(()))
153 .transpose()?,
154 serialized
155 .requested
156 .map(|val| Finite::new(val).ok_or(()))
157 .transpose()?,
158 CanGc::from_cx(cx),
159 ))
160 }
161
162 fn serialized_storage<'a>(
164 data: StructuredData<'a, '_>,
165 ) -> &'a mut Option<FxHashMap<QuotaExceededErrorId, Self::Data>> {
166 match data {
167 StructuredData::Reader(reader) => &mut reader.quota_exceeded_errors,
168 StructuredData::Writer(writer) => &mut writer.quota_exceeded_errors,
169 }
170 }
171}