New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement the MozMap type. #13332
Merged
+254
−54
Merged
Implement the MozMap type. #13332
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
6023560
Improve jsid_to_str's name and documentation.
Ms2ger d1d2074
Improve handling of ConversionResult::Failure in unions.
Ms2ger e942f50
Handle unsupported types better in getUnionTypeTemplateVars.
Ms2ger b2fc80a
Rename innerSequenceType to innerContainerType.
Ms2ger 9371889
Use innerContainerType in getConversionConfigForType.
Ms2ger 9a9ca45
Introduce wrapInNativeContainerType.
Ms2ger 2d83e5a
Implement the MozMap type.
Ms2ger File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.
Loading status checks…
Implement the MozMap type.
Fixes #13144.
- Loading branch information
commit 2d83e5a78880724713366a38f599a1dac65403dc
| @@ -0,0 +1,109 @@ | ||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||
| * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| //! The `MozMap` (open-ended dictionary) type. | ||
|
|
||
| use dom::bindings::conversions::jsid_to_string; | ||
| use dom::bindings::str::DOMString; | ||
| use js::conversions::{FromJSValConvertible, ToJSValConvertible, ConversionResult}; | ||
| use js::jsapi::GetPropertyKeys; | ||
| use js::jsapi::HandleValue; | ||
| use js::jsapi::JSContext; | ||
| use js::jsapi::JSITER_OWNONLY; | ||
| use js::jsapi::JSPROP_ENUMERATE; | ||
| use js::jsapi::JS_DefineUCProperty2; | ||
| use js::jsapi::JS_GetPropertyById; | ||
| use js::jsapi::JS_NewPlainObject; | ||
| use js::jsapi::MutableHandleValue; | ||
| use js::jsval::ObjectValue; | ||
| use js::jsval::UndefinedValue; | ||
| use js::rust::IdVector; | ||
| use std::collections::HashMap; | ||
| use std::ops::Deref; | ||
|
|
||
| /// The `MozMap` (open-ended dictionary) type. | ||
| pub struct MozMap<T> { | ||
| map: HashMap<DOMString, T>, | ||
| } | ||
|
|
||
| impl<T> MozMap<T> { | ||
| /// Create an empty `MozMap`. | ||
| pub fn new() -> Self { | ||
| MozMap { | ||
| map: HashMap::new(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl<T> Deref for MozMap<T> { | ||
| type Target = HashMap<DOMString, T>; | ||
|
|
||
| fn deref(&self) -> &HashMap<DOMString, T> { | ||
| &self.map | ||
| } | ||
| } | ||
|
|
||
| impl<T, C> FromJSValConvertible for MozMap<T> | ||
| where T: FromJSValConvertible<Config=C>, | ||
| C: Clone, | ||
| { | ||
| type Config = C; | ||
| unsafe fn from_jsval(cx: *mut JSContext, value: HandleValue, config: C) | ||
| -> Result<ConversionResult<Self>, ()> { | ||
| if !value.is_object() { | ||
| return Ok(ConversionResult::Failure("MozMap value was not an object".into())); | ||
| } | ||
|
|
||
| rooted!(in(cx) let object = value.to_object()); | ||
| let ids = IdVector::new(cx); | ||
| assert!(GetPropertyKeys(cx, object.handle(), JSITER_OWNONLY, ids.get())); | ||
|
|
||
| let mut map = HashMap::new(); | ||
| for id in &*ids { | ||
| rooted!(in(cx) let id = *id); | ||
|
|
||
| rooted!(in(cx) let mut property = UndefinedValue()); | ||
| if !JS_GetPropertyById(cx, object.handle(), id.handle(), property.handle_mut()) { | ||
| return Err(()); | ||
| } | ||
|
|
||
| let property = match try!(T::from_jsval(cx, property.handle(), config.clone())) { | ||
| ConversionResult::Success(property) => property, | ||
| ConversionResult::Failure(message) => return Ok(ConversionResult::Failure(message)), | ||
Ms2ger
Author
Contributor
|
||
| }; | ||
|
|
||
| let key = jsid_to_string(cx, id.handle()).unwrap(); | ||
|
||
| map.insert(key, property); | ||
| } | ||
|
|
||
| Ok(ConversionResult::Success(MozMap { | ||
| map: map, | ||
| })) | ||
| } | ||
| } | ||
|
|
||
| impl<T: ToJSValConvertible> ToJSValConvertible for MozMap<T> { | ||
| #[inline] | ||
| unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { | ||
| rooted!(in(cx) let js_object = JS_NewPlainObject(cx)); | ||
| assert!(!js_object.handle().is_null()); | ||
|
|
||
| rooted!(in(cx) let mut js_value = UndefinedValue()); | ||
| for (key, value) in &self.map { | ||
| let key = key.encode_utf16().collect::<Vec<_>>(); | ||
| value.to_jsval(cx, js_value.handle_mut()); | ||
|
|
||
| assert!(JS_DefineUCProperty2(cx, | ||
| js_object.handle(), | ||
| key.as_ptr(), | ||
| key.len(), | ||
| js_value.handle(), | ||
| JSPROP_ENUMERATE, | ||
| None, | ||
| None)); | ||
| } | ||
|
|
||
| rval.set(ObjectValue(&*js_object.handle().get())); | ||
| } | ||
| } | ||
ProTip!
Use n and p to navigate between commits in a pull request.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Relevant option?