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::{
14 reflect_dom_object_with_cx, reflect_dom_object_with_proto_and_cx,
15};
16use script_bindings::root::DomRoot;
17use script_bindings::str::DOMString;
18use servo_base::id::{QuotaExceededErrorId, QuotaExceededErrorIndex};
19use servo_constellation_traits::SerializableQuotaExceededError;
20
21use crate::dom::bindings::error::Error;
22use crate::dom::bindings::serializable::Serializable;
23use crate::dom::bindings::structuredclone::StructuredData;
24use crate::dom::types::{DOMException, GlobalScope};
25
26#[dom_struct]
28pub(crate) struct QuotaExceededError {
29 dom_exception: DOMException,
31 quota: Option<Finite<f64>>,
33 requested: Option<Finite<f64>>,
35}
36
37impl QuotaExceededError {
38 fn new_inherited(
39 message: DOMString,
40 quota: Option<Finite<f64>>,
41 requested: Option<Finite<f64>>,
42 ) -> Self {
43 Self {
44 dom_exception: DOMException::new_inherited(message, "QuotaExceededError".into()),
45 quota,
46 requested,
47 }
48 }
49
50 pub(crate) fn new(
51 cx: &mut JSContext,
52 global: &GlobalScope,
53 message: DOMString,
54 quota: Option<Finite<f64>>,
55 requested: Option<Finite<f64>>,
56 ) -> DomRoot<Self> {
57 reflect_dom_object_with_cx(
58 Box::new(Self::new_inherited(message, quota, requested)),
59 global,
60 cx,
61 )
62 }
63}
64
65impl QuotaExceededErrorMethods<crate::DomTypeHolder> for QuotaExceededError {
66 fn Constructor(
68 cx: &mut JSContext,
69 global: &GlobalScope,
70 proto: Option<HandleObject>,
71 message: DOMString,
72 options: &QuotaExceededErrorOptions,
73 ) -> Result<DomRoot<Self>, Error> {
74 if let Some(quota) = options.quota {
76 if *quota < 0.0 {
78 return Err(Error::Range(
79 c"quota must be at least zero if present".to_owned(),
80 ));
81 }
82 }
83 if let Some(requested) = options.requested {
85 if *requested < 0.0 {
87 return Err(Error::Range(
88 c"requested must be at least zero if present".to_owned(),
89 ));
90 }
91 }
92 if let (Some(quota), Some(requested)) = (options.quota, options.requested) &&
95 *requested < *quota
96 {
97 return Err(Error::Range(c"requested is less than quota".to_owned()));
98 }
99 Ok(reflect_dom_object_with_proto_and_cx(
100 Box::new(QuotaExceededError::new_inherited(
101 message,
102 options.quota,
103 options.requested,
104 )),
105 global,
106 proto,
107 cx,
108 ))
109 }
110
111 fn GetQuota(&self) -> Option<Finite<f64>> {
113 self.quota
115 }
116
117 fn GetRequested(&self) -> Option<Finite<f64>> {
119 self.requested
121 }
122}
123
124impl Serializable for QuotaExceededError {
125 type Index = QuotaExceededErrorIndex;
126 type Data = SerializableQuotaExceededError;
127
128 fn serialize(&self) -> Result<(QuotaExceededErrorId, Self::Data), ()> {
130 let (_, dom_exception) = self.dom_exception.serialize()?;
131 let serialized = SerializableQuotaExceededError {
132 dom_exception,
133 quota: self.quota.as_deref().copied(),
134 requested: self.requested.as_deref().copied(),
135 };
136 Ok((QuotaExceededErrorId::new(), serialized))
137 }
138
139 fn deserialize(
141 cx: &mut JSContext,
142 owner: &GlobalScope,
143 serialized: Self::Data,
144 ) -> Result<DomRoot<Self>, ()>
145 where
146 Self: Sized,
147 {
148 Ok(Self::new(
149 cx,
150 owner,
151 DOMString::from(serialized.dom_exception.message),
152 serialized
153 .quota
154 .map(|val| Finite::new(val).ok_or(()))
155 .transpose()?,
156 serialized
157 .requested
158 .map(|val| Finite::new(val).ok_or(()))
159 .transpose()?,
160 ))
161 }
162
163 fn serialized_storage<'a>(
165 data: StructuredData<'a, '_>,
166 ) -> &'a mut Option<FxHashMap<QuotaExceededErrorId, Self::Data>> {
167 match data {
168 StructuredData::Reader(reader) => &mut reader.quota_exceeded_errors,
169 StructuredData::Writer(writer) => &mut writer.quota_exceeded_errors,
170 }
171 }
172}