Skip to main content

script/dom/
quotaexceedederror.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use 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/// <https://webidl.spec.whatwg.org/#quotaexceedederror>
27#[dom_struct]
28pub(crate) struct QuotaExceededError {
29    /// <https://webidl.spec.whatwg.org/#idl-DOMException>
30    dom_exception: DOMException,
31    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quota>
32    quota: Option<Finite<f64>>,
33    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-requested>
34    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    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quotaexceedederror>
67    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 options["quota"] is present:
75        if let Some(quota) = options.quota {
76            // If options["quota"] is less than 0, then throw a RangeError.
77            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 options["requested"] is present:
84        if let Some(requested) = options.requested {
85            // If options["requested"] is less than 0, then throw a RangeError.
86            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 this’s quota is not null, this’s requested is not null, and this’s requested
93        // is less than this’s quota, then throw a RangeError.
94        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    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quota>
112    fn GetQuota(&self) -> Option<Finite<f64>> {
113        // The quota getter steps are to return this’s quota.
114        self.quota
115    }
116
117    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-requested>
118    fn GetRequested(&self) -> Option<Finite<f64>> {
119        // The requested getter steps are to return this’s requested.
120        self.requested
121    }
122}
123
124impl Serializable for QuotaExceededError {
125    type Index = QuotaExceededErrorIndex;
126    type Data = SerializableQuotaExceededError;
127
128    /// <https://webidl.spec.whatwg.org/#quotaexceedederror>
129    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    /// <https://webidl.spec.whatwg.org/#quotaexceedederror>
140    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    /// <https://webidl.spec.whatwg.org/#quotaexceedederror>
164    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}