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