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 base::id::{QuotaExceededErrorId, QuotaExceededErrorIndex};
6use constellation_traits::SerializableQuotaExceededError;
7use dom_struct::dom_struct;
8use js::gc::HandleObject;
9use rustc_hash::FxHashMap;
10use script_bindings::codegen::GenericBindings::QuotaExceededErrorBinding::{
11    QuotaExceededErrorMethods, QuotaExceededErrorOptions,
12};
13use script_bindings::num::Finite;
14use script_bindings::root::DomRoot;
15use script_bindings::script_runtime::CanGc;
16use script_bindings::str::DOMString;
17
18use crate::dom::bindings::error::Error;
19use crate::dom::bindings::reflector::{reflect_dom_object, reflect_dom_object_with_proto};
20use crate::dom::bindings::serializable::Serializable;
21use crate::dom::bindings::structuredclone::StructuredData;
22use crate::dom::types::{DOMException, GlobalScope};
23
24/// <https://webidl.spec.whatwg.org/#quotaexceedederror>
25#[dom_struct]
26pub(crate) struct QuotaExceededError {
27    /// <https://webidl.spec.whatwg.org/#idl-DOMException>
28    dom_exception: DOMException,
29    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quota>
30    quota: Option<Finite<f64>>,
31    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-requested>
32    requested: Option<Finite<f64>>,
33}
34
35impl QuotaExceededError {
36    fn new_inherited(
37        message: DOMString,
38        quota: Option<Finite<f64>>,
39        requested: Option<Finite<f64>>,
40    ) -> Self {
41        Self {
42            dom_exception: DOMException::new_inherited(
43                message,
44                DOMString::from_string("QuotaExceededError".to_string()),
45            ),
46            quota,
47            requested,
48        }
49    }
50
51    pub(crate) fn new(
52        global: &GlobalScope,
53        message: DOMString,
54        quota: Option<Finite<f64>>,
55        requested: Option<Finite<f64>>,
56        can_gc: CanGc,
57    ) -> DomRoot<Self> {
58        reflect_dom_object(
59            Box::new(Self::new_inherited(message, quota, requested)),
60            global,
61            can_gc,
62        )
63    }
64}
65
66impl QuotaExceededErrorMethods<crate::DomTypeHolder> for QuotaExceededError {
67    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quotaexceedederror>
68    fn Constructor(
69        global: &GlobalScope,
70        proto: Option<HandleObject>,
71        can_gc: CanGc,
72        message: DOMString,
73        options: &QuotaExceededErrorOptions,
74    ) -> Result<DomRoot<Self>, Error> {
75        // If options["quota"] is present:
76        if let Some(quota) = options.quota {
77            // If options["quota"] is less than 0, then throw a RangeError.
78            if *quota < 0.0 {
79                return Err(Error::Range(
80                    "quota must be at least zero if present".to_string(),
81                ));
82            }
83        }
84        // If options["requested"] is present:
85        if let Some(requested) = options.requested {
86            // If options["requested"] is less than 0, then throw a RangeError.
87            if *requested < 0.0 {
88                return Err(Error::Range(
89                    "requested must be at least zero if present".to_string(),
90                ));
91            }
92        }
93        // If this’s quota is not null, this’s requested is not null, and this’s requested
94        // is less than this’s quota, then throw a RangeError.
95        if let (Some(quota), Some(requested)) = (options.quota, options.requested) {
96            if *requested < *quota {
97                return Err(Error::Range("requested is less than quota".to_string()));
98            }
99        }
100        Ok(reflect_dom_object_with_proto(
101            Box::new(QuotaExceededError::new_inherited(
102                message,
103                options.quota,
104                options.requested,
105            )),
106            global,
107            proto,
108            can_gc,
109        ))
110    }
111
112    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quota>
113    fn GetQuota(&self) -> Option<Finite<f64>> {
114        // The quota getter steps are to return this’s quota.
115        self.quota
116    }
117
118    /// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-requested>
119    fn GetRequested(&self) -> Option<Finite<f64>> {
120        // The requested getter steps are to return this’s requested.
121        self.requested
122    }
123}
124
125impl Serializable for QuotaExceededError {
126    type Index = QuotaExceededErrorIndex;
127    type Data = SerializableQuotaExceededError;
128
129    /// <https://webidl.spec.whatwg.org/#quotaexceedederror>
130    fn serialize(&self) -> Result<(QuotaExceededErrorId, Self::Data), ()> {
131        let (_, dom_exception) = self.dom_exception.serialize()?;
132        let serialized = SerializableQuotaExceededError {
133            dom_exception,
134            quota: self.quota.as_deref().copied(),
135            requested: self.requested.as_deref().copied(),
136        };
137        Ok((QuotaExceededErrorId::new(), serialized))
138    }
139
140    /// <https://webidl.spec.whatwg.org/#quotaexceedederror>
141    fn deserialize(
142        owner: &GlobalScope,
143        serialized: Self::Data,
144        can_gc: CanGc,
145    ) -> Result<DomRoot<Self>, ()>
146    where
147        Self: Sized,
148    {
149        Ok(Self::new(
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            can_gc,
161        ))
162    }
163
164    /// <https://webidl.spec.whatwg.org/#quotaexceedederror>
165    fn serialized_storage<'a>(
166        data: StructuredData<'a, '_>,
167    ) -> &'a mut Option<FxHashMap<QuotaExceededErrorId, Self::Data>> {
168        match data {
169            StructuredData::Reader(reader) => &mut reader.quota_exceeded_errors,
170            StructuredData::Writer(writer) => &mut writer.quota_exceeded_errors,
171        }
172    }
173}