Added Geary
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
From 89453931bf6743049644274fc730a10e7bd2a53d Mon Sep 17 00:00:00 2001
|
||||
From: Michael Gratton <mike@vee.net>
|
||||
Date: Fri, 28 Aug 2020 11:20:27 +1000
|
||||
Subject: [PATCH 074/124] Util.Js: Improve JSC Value to GLib.Variant conversion
|
||||
|
||||
Stop needlessly wrapping object members and array elements in
|
||||
variant variants.
|
||||
|
||||
Don't wrap object values in variants since the code is already using
|
||||
vardicts for these. Return a variant array if a JS array contains values
|
||||
of all the same type and don't wrap these in variants, else return
|
||||
a tuple, which don't need to be wrapped either.
|
||||
---
|
||||
src/client/util/util-js.vala | 160 +++++++++++++++++++++--------
|
||||
test/client/util/util-js-test.vala | 28 ++++-
|
||||
2 files changed, 143 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/src/client/util/util-js.vala b/src/client/util/util-js.vala
|
||||
index d2ce9f2e..095f9da4 100644
|
||||
--- a/src/client/util/util-js.vala
|
||||
+++ b/src/client/util/util-js.vala
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright 2017,2019 Michael James Gratton <mike@vee.net>
|
||||
+ * Copyright © 2017-2020 Michael Gratton <mike@vee.net>
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
@@ -25,6 +25,64 @@ namespace Util.JS {
|
||||
TYPE
|
||||
}
|
||||
|
||||
+ /** Supported types of JSC values. */
|
||||
+ public enum JscType {
|
||||
+
|
||||
+ /** Specifies an unsupported value type. */
|
||||
+ UNKNOWN,
|
||||
+
|
||||
+ /** Specifies a JavaScript `undefined` value. */
|
||||
+ UNDEFINED,
|
||||
+
|
||||
+ /** Specifies a JavaScript `null` value. */
|
||||
+ NULL,
|
||||
+ FUNCTION,
|
||||
+ STRING,
|
||||
+ NUMBER,
|
||||
+ BOOLEAN,
|
||||
+ ARRAY,
|
||||
+ CONSTRUCTOR,
|
||||
+ OBJECT;
|
||||
+
|
||||
+ /**
|
||||
+ * Determines the type of a JSC value.
|
||||
+ *
|
||||
+ * Returns the type of the given value, or {@link UNKNOWN} if
|
||||
+ * it could not be determined.
|
||||
+ */
|
||||
+ public static JscType to_type(JSC.Value value) {
|
||||
+ if (value.is_undefined()) {
|
||||
+ return UNDEFINED;
|
||||
+ }
|
||||
+ if (value.is_null()) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (value.is_string()) {
|
||||
+ return STRING;
|
||||
+ }
|
||||
+ if (value.is_number()) {
|
||||
+ return NUMBER;
|
||||
+ }
|
||||
+ if (value.is_boolean()) {
|
||||
+ return BOOLEAN;
|
||||
+ }
|
||||
+ if (value.is_array()) {
|
||||
+ return ARRAY;
|
||||
+ }
|
||||
+ if (value.is_object()) {
|
||||
+ return OBJECT;
|
||||
+ }
|
||||
+ if (value.is_function()) {
|
||||
+ return FUNCTION;
|
||||
+ }
|
||||
+ if (value.is_constructor()) {
|
||||
+ return CONSTRUCTOR;
|
||||
+ }
|
||||
+ return UNKNOWN;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Returns a JSC Value as a bool.
|
||||
*
|
||||
@@ -132,60 +190,80 @@ namespace Util.JS {
|
||||
*
|
||||
* Simple value objects (string, number, and Boolean values),
|
||||
* arrays of these, and objects with these types as properties are
|
||||
- * supported. Arrays are converted to arrays of variants, and
|
||||
- * objects to dictionaries containing string keys and variant
|
||||
- * values. Null or undefined values are returned as an empty maybe
|
||||
- * variant type, since it is not possible to determine the actual
|
||||
- * type.
|
||||
+ * supported. Arrays containing objects of the same type are
|
||||
+ * converted to arrays, otherwise they are converted to tuples,
|
||||
+ * empty arrays are converted to the unit tuple, and objects are
|
||||
+ * converted to vardict containing property names as keys and
|
||||
+ * values. Null and undefined values are returned as an empty
|
||||
+ * maybe variant type, since it is not possible to determine the
|
||||
+ * actual type.
|
||||
*
|
||||
* Throws a type error if the given value's type is not supported.
|
||||
*/
|
||||
public inline GLib.Variant value_to_variant(JSC.Value value)
|
||||
throws Error {
|
||||
- if (value.is_null() || value.is_undefined()) {
|
||||
- return new GLib.Variant.maybe(GLib.VariantType.VARIANT, null);
|
||||
- }
|
||||
- if (value.is_boolean()) {
|
||||
- return new GLib.Variant.boolean(value.to_boolean());
|
||||
- }
|
||||
- if (value.is_number()) {
|
||||
- return new GLib.Variant.double(value.to_double());
|
||||
- }
|
||||
- if (value.is_string()) {
|
||||
- return new GLib.Variant.string(value.to_string());
|
||||
- }
|
||||
- if (value.is_array()) {
|
||||
+ GLib.Variant? variant = null;
|
||||
+ switch (JscType.to_type(value)) {
|
||||
+ case UNDEFINED:
|
||||
+ case NULL:
|
||||
+ variant = new GLib.Variant.maybe(GLib.VariantType.VARIANT, null);
|
||||
+ break;
|
||||
+
|
||||
+ case STRING:
|
||||
+ variant = new GLib.Variant.string(value.to_string());
|
||||
+ break;
|
||||
+
|
||||
+ case NUMBER:
|
||||
+ variant = new GLib.Variant.double(value.to_double());
|
||||
+ break;
|
||||
+
|
||||
+ case BOOLEAN:
|
||||
+ variant = new GLib.Variant.boolean(value.to_boolean());
|
||||
+ break;
|
||||
+
|
||||
+ case ARRAY:
|
||||
int len = to_int32(value.object_get_property("length"));
|
||||
- GLib.Variant[] values = new GLib.Variant[len];
|
||||
- for (int i = 0; i < len; i++) {
|
||||
- values[i] = new GLib.Variant.variant(
|
||||
- value_to_variant(value.object_get_property_at_index(i))
|
||||
- );
|
||||
+ if (len == 0) {
|
||||
+ variant = new GLib.Variant.tuple({});
|
||||
+ } else {
|
||||
+ JSC.Value element = value.object_get_property_at_index(0);
|
||||
+ var first_type = JscType.to_type(element);
|
||||
+ var all_same_type = true;
|
||||
+ var values = new GLib.Variant[len];
|
||||
+ values[0] = value_to_variant(element);
|
||||
+ for (int i = 1; i < len; i++) {
|
||||
+ element = value.object_get_property_at_index(i);
|
||||
+ values[i] = value_to_variant(element);
|
||||
+ all_same_type &= (first_type == JscType.to_type(element));
|
||||
+ }
|
||||
+ if (!all_same_type) {
|
||||
+ variant = new GLib.Variant.tuple(values);
|
||||
+ } else {
|
||||
+ variant = new GLib.Variant.array(
|
||||
+ values[0].get_type(), values
|
||||
+ );
|
||||
+ }
|
||||
}
|
||||
- return new GLib.Variant.array(GLib.VariantType.VARIANT, values);
|
||||
- }
|
||||
- if (value.is_object()) {
|
||||
+ break;
|
||||
+
|
||||
+ case OBJECT:
|
||||
GLib.VariantDict dict = new GLib.VariantDict();
|
||||
string[] names = value.object_enumerate_properties();
|
||||
if (names != null) {
|
||||
foreach (var name in names) {
|
||||
- try {
|
||||
- dict.insert_value(
|
||||
- name,
|
||||
- new GLib.Variant.variant(
|
||||
- value_to_variant(
|
||||
- value.object_get_property(name)
|
||||
- )
|
||||
- )
|
||||
- );
|
||||
- } catch (Error.TYPE err) {
|
||||
- // ignored
|
||||
- }
|
||||
+ dict.insert_value(
|
||||
+ name,
|
||||
+ value_to_variant(value.object_get_property(name))
|
||||
+ );
|
||||
}
|
||||
}
|
||||
- return dict.end();
|
||||
+ variant = dict.end();
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ throw new Error.TYPE("Unsupported JS type: %s", value.to_string());
|
||||
}
|
||||
- throw new Error.TYPE("Unsupported JS type: %s", value.to_string());
|
||||
+ return variant;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/test/client/util/util-js-test.vala b/test/client/util/util-js-test.vala
|
||||
index 16a01d83..f1da043d 100644
|
||||
--- a/test/client/util/util-js-test.vala
|
||||
+++ b/test/client/util/util-js-test.vala
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright 2017 Michael Gratton <mike@vee.net>
|
||||
+ * Copyright © 2017-2020 Michael Gratton <mike@vee.net>
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
@@ -61,15 +61,35 @@ public class Util.JS.Test : TestCase {
|
||||
var value = new JSC.Value.array_from_garray(this.context, null);
|
||||
assert_equal(
|
||||
value_to_variant(value).print(true),
|
||||
- "@av []"
|
||||
+ "()"
|
||||
);
|
||||
+
|
||||
var array = new GLib.GenericArray<JSC.Value>();
|
||||
array.add(new JSC.Value.string(this.context, "test"));
|
||||
value = new JSC.Value.array_from_garray(this.context, array);
|
||||
assert_equal(
|
||||
value_to_variant(value).print(true),
|
||||
- "[<'test'>]"
|
||||
+ "['test']"
|
||||
);
|
||||
+
|
||||
+ array = new GLib.GenericArray<JSC.Value>();
|
||||
+ array.add(new JSC.Value.string(this.context, "test1"));
|
||||
+ array.add(new JSC.Value.string(this.context, "test2"));
|
||||
+ value = new JSC.Value.array_from_garray(this.context, array);
|
||||
+ assert_equal(
|
||||
+ value_to_variant(value).print(true),
|
||||
+ "['test1', 'test2']"
|
||||
+ );
|
||||
+
|
||||
+ array = new GLib.GenericArray<JSC.Value>();
|
||||
+ array.add(new JSC.Value.string(this.context, "test"));
|
||||
+ array.add(new JSC.Value.boolean(this.context, true));
|
||||
+ value = new JSC.Value.array_from_garray(this.context, array);
|
||||
+ assert_equal(
|
||||
+ value_to_variant(value).print(true),
|
||||
+ "('test', true)"
|
||||
+ );
|
||||
+
|
||||
value = new JSC.Value.object(this.context, null, null);
|
||||
assert_equal(
|
||||
value_to_variant(value).print(true),
|
||||
@@ -80,7 +100,7 @@ public class Util.JS.Test : TestCase {
|
||||
);
|
||||
assert_equal(
|
||||
value_to_variant(value).print(true),
|
||||
- "{'test': <<true>>}"
|
||||
+ "{'test': <true>}"
|
||||
);
|
||||
}
|
||||
|
||||
--
|
||||
2.29.2
|
||||
|
||||
Reference in New Issue
Block a user