ion/flags.rs
1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 */
6
7use std::fmt::{Display, Formatter};
8use std::{fmt, str};
9
10use arrayvec::ArrayVec;
11use bitflags::{Flags as _, bitflags};
12use mozjs::jsapi::{
13 JSITER_FORAWAITOF, JSITER_HIDDEN, JSITER_OWNONLY, JSITER_PRIVATE, JSITER_SYMBOLS, JSITER_SYMBOLSONLY,
14 JSPROP_ENUMERATE, JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_RESOLVING, RegExpFlag_DotAll, RegExpFlag_Global,
15 RegExpFlag_HasIndices, RegExpFlag_IgnoreCase, RegExpFlag_Multiline, RegExpFlag_Sticky, RegExpFlag_Unicode,
16 RegExpFlags as REFlags,
17};
18
19bitflags! {
20 /// Represents the flags of properties on an [Object](crate::Object)
21 #[derive(Clone, Copy, Debug)]
22 pub struct PropertyFlags: u16 {
23 /// Allows enumeration through `Object.keys()`, `for...in` and other functions.
24 /// See [Enumerability of Properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#traversing_object_properties).
25 const ENUMERATE = JSPROP_ENUMERATE as u16;
26 /// Prevents reassignment of the property.
27 const READ_ONLY = JSPROP_READONLY as u16;
28 /// Prevents deletion and attribute modification of the property.
29 const PERMANENT = JSPROP_PERMANENT as u16;
30 const RESOLVING = JSPROP_RESOLVING as u16;
31
32 const CONSTANT = PropertyFlags::READ_ONLY.bits() | PropertyFlags::PERMANENT.bits();
33 const CONSTANT_ENUMERATED = PropertyFlags::CONSTANT.bits() | PropertyFlags::ENUMERATE.bits();
34 }
35}
36
37bitflags! {
38 /// Represents the flags when iterating over an [Object](crate::Object).
39 #[derive(Clone, Copy, Debug, Default)]
40 pub struct IteratorFlags: u32 {
41 /// Allows iterating over private properties.
42 const PRIVATE = JSITER_PRIVATE;
43 /// Disallows iterating over inherited properties.
44 const OWN_ONLY = JSITER_OWNONLY;
45 /// Allows iteration over non-enumerable properties.
46 const HIDDEN = JSITER_HIDDEN;
47 /// Allows iteration over symbol keys.
48 const SYMBOLS = JSITER_SYMBOLS;
49 /// Disallows iteration over string keys.
50 const SYMBOLS_ONLY = JSITER_SYMBOLSONLY;
51 /// Iteration over async iterable objects and async generators.
52 const FOR_AWAIT_OF = JSITER_FORAWAITOF;
53 }
54}
55
56bitflags! {
57 /// Represents the flags of a [RegExp](crate::RegExp) object.
58 /// See [Advanced searching with flags](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions#advanced_searching_with_flags)
59 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
60 pub struct RegExpFlags: u8 {
61 /// Determines if indices are generated for matches. Represents `d` flag.
62 /// See [hasIndices](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/hasIndices).
63 const HAS_INDICES = RegExpFlag_HasIndices;
64 /// Determines if search is global. Represents `g` flag.
65 /// See [global](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global).
66 const GLOBAL = RegExpFlag_Global;
67 /// Determines if search ignores case. Represents `i` flag.
68 /// See [ignoreCase](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase).
69 const IGNORE_CASE = RegExpFlag_IgnoreCase;
70 /// Determines if `^` and `$` match newline characters. Represents `m` flag.
71 /// See [multiline](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/multiline).
72 const MULTILINE = RegExpFlag_Multiline;
73 /// Determines if `.` matches newline characters. Represents `s` flag.
74 /// See [dotAll](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll).
75 const DOT_ALL = RegExpFlag_DotAll;
76 /// Determines if pattern uses unicode semantics. Represents `u` flag.
77 /// See [unicode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode).
78 const UNICODE = RegExpFlag_Unicode;
79 /// Determines if search is continued from current index. Represents `y` flag.
80 /// See [sticky](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky).
81 const STICKY = RegExpFlag_Sticky;
82 }
83}
84
85impl Display for RegExpFlags {
86 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
87 let mut flags = ArrayVec::<_, 8>::new();
88 for flag in RegExpFlags::FLAGS {
89 if self.contains(*flag.value()) {
90 match *flag.value() {
91 RegExpFlags::HAS_INDICES => flags.push(b'd'),
92 RegExpFlags::GLOBAL => flags.push(b'g'),
93 RegExpFlags::IGNORE_CASE => flags.push(b'i'),
94 RegExpFlags::MULTILINE => flags.push(b'm'),
95 RegExpFlags::DOT_ALL => flags.push(b's'),
96 RegExpFlags::UNICODE => flags.push(b'u'),
97 RegExpFlags::STICKY => flags.push(b'y'),
98 _ => (),
99 }
100 }
101 }
102 flags.sort_unstable();
103 f.write_str(unsafe { str::from_utf8_unchecked(&flags) })
104 }
105}
106
107impl From<RegExpFlags> for REFlags {
108 fn from(flags: RegExpFlags) -> Self {
109 REFlags { flags_: flags.bits() }
110 }
111}
112
113impl From<REFlags> for RegExpFlags {
114 fn from(flags: REFlags) -> RegExpFlags {
115 RegExpFlags::from_bits_retain(flags.flags_)
116 }
117}