ソースを参照

Fix mapping bugs and APIs

Billy Barrow 10 ヶ月 前
コミット
d1e5b3f7f7

+ 10 - 0
src/json/Object.vala

@@ -76,6 +76,16 @@ namespace InvercargillJson {
             return null;
         }
 
+        public void set_native<T>(string key, T value) throws ElementError {
+            set(key, new JsonElement.from_element(new NativeElement<T>(value)));
+        }
+
+        public JsonElement as_element() {
+            var node = new Json.Node(Json.NodeType.OBJECT);
+            node.take_object(object);
+            return new JsonElement.from_node(node);
+        }
+
     }
 
 }

+ 5 - 1
src/lib/Associative/Properties.vala

@@ -2,9 +2,13 @@
 namespace Invercargill {
 
     public interface Properties : Enumerable<KeyValuePair<string, Element>>, KeyValues<string, Element> {
+        public abstract void set_native<T>(string key, T value) throws ElementError;
     }
 
-    private class DictionaryProperties : Dictionary<string, Element>, Properties {
+    public class PropertiesDictionary : Dictionary<string, Element>, Properties {
+        public void set_native<T>(string key, T value) throws ElementError {
+            this[key] = new NativeElement<T>(value);
+        }
     }
 
 }

+ 0 - 2
src/lib/Collections/BinaryData.vala

@@ -461,8 +461,6 @@ namespace Invercargill {
             append_byte_array(bin);
             amount -= data.length;
             return amount != 0;
-
-            //328893
         }
 
         public Enumerable<uint8> wrap(Enumerable<uint8> enumerable) {

+ 8 - 0
src/lib/Collections/Set.vala

@@ -8,7 +8,15 @@ namespace Invercargill {
         private HashFunc<T> hash_func;
         private EqualFunc<T> equal_func;
 
+        construct {
+            setup();
+        }
+
         public Set(HashFunc<T>? value_hash_func = null, EqualFunc<T>? value_equal_func = null) {
+            setup(value_hash_func, value_equal_func);
+        }
+
+        private void setup(HashFunc<T>? value_hash_func = null, EqualFunc<T>? value_equal_func = null) {
             hash_func = value_hash_func;
             equal_func = value_equal_func;
 

+ 2 - 0
src/lib/Delegates.vala

@@ -6,6 +6,8 @@ namespace Invercargill {
 
     public delegate Tout TransformDelegate<Tin, Tout>(Tin item);
 
+    public delegate Tout ErrorTransformDelegate<Tin, Tout>(Tin item) throws Error;
+
     public delegate bool PredicateDelegate<T>(T item);
 
     public delegate Taggrigate AggrigateDelegate<Taggrigate, Tin>(Taggrigate aggrigate, Tin item);

+ 3 - 0
src/lib/Element.vala

@@ -112,6 +112,9 @@ namespace Invercargill {
         }
 
         public bool is_null() {
+            if(type().is_a(typeof(bool))) {
+                return false;
+            }
             return object == null;
         }
 

+ 8 - 0
src/lib/Enumerable.vala

@@ -87,6 +87,14 @@ namespace Invercargill {
             return new FilterQuery<T>(this, (owned)predicate);
         }
 
+        public virtual Enumerable<T> from(owned PredicateDelegate<T> predicate) {
+            return new FromQuery<T>(this, (owned)predicate);
+        }
+
+        public virtual Enumerable<T> until(owned PredicateDelegate<T> predicate) {
+            return new UntilQuery<T>(this, (owned)predicate);
+        }
+
         public virtual Enumerable<Tout> select_where<Tout>(owned FilterTransformDelegate<T, Tout> transform) {
             return new FilterTransformQuery<T, Tout>(this, (owned)transform);
         }

+ 26 - 16
src/lib/PropertyMapper.vala

@@ -1,7 +1,9 @@
 namespace Invercargill {
 
     public delegate TProp PropertyGetter<TClass, TProp>(TClass object);
-    public delegate void PropertySetter<TClass, TProp>(TClass object, TProp value) throws IndexError, ElementError;
+    public delegate void PropertySetter<TClass, TProp>(TClass object, TProp value) throws Error;
+    public delegate Tout PropertyGetterTransformer<Tin, Tout>(Tin object);
+    public delegate Tout PropertySetterTransformer<Tin, Tout>(Tin object) throws Error;
     public delegate T ObjectConstructor<T>();
     public class PropertyMapper<T> {
 
@@ -13,22 +15,28 @@ namespace Invercargill {
             this.constructor = constructor;
         }
 
-        public void map_into(T object, KeyValues<string, Element> properties) throws IndexError, ElementError {
+        public void map_into(T object, KeyValues<string, Element> properties) throws Error {
             foreach (var mapping in mappings) {
+                if(!mapping.mandatory && !properties.has(mapping.name)) {
+                    continue;
+                }
                 mapping.setter(object, properties[mapping.name]);
             }
         }
 
-        public T materialise(Properties properties) throws IndexError, ElementError {
+        public T materialise(Properties properties) throws Error {
             var obj = constructor();
             map_into(obj, properties);
             return obj;
         }
 
         public Properties map_from(T object) {
-            var properties = new DictionaryProperties();
+            var properties = new PropertiesDictionary();
             foreach (var mapping in mappings) {
-                properties[mapping.name] = mapping.getter(object);
+                var val = mapping.getter(object);
+                if(mapping.mandatory || !val.is_null()) {
+                    properties[mapping.name] = val;
+                }
             }
             return properties;
         }
@@ -37,6 +45,7 @@ namespace Invercargill {
 
     private class PropertyMapping<T> {
         public string name;
+        public bool mandatory;
         public PropertyGetter<T, Element> getter;
         public PropertySetter<T, Element> setter;
     }
@@ -51,10 +60,11 @@ namespace Invercargill {
             constructor = () => Object.new(typeof(T));
         }
 
-        public PropertyMapperBuilder<T> map<TProp>(string name, owned PropertyGetter<T, TProp> getter, owned PropertySetter<T, TProp> setter) {
+        public PropertyMapperBuilder<T> map<TProp>(string name, owned PropertyGetter<T, TProp> getter, owned PropertySetter<T, TProp> setter, bool mandatory = true) {
             if(typeof(TProp).is_a(typeof(Element))) {
                 add_mapping(new PropertyMapping<T>() {
                     name = name,
+                    mandatory = mandatory,
                     getter = (owned)getter,
                     setter = (owned)setter
                 });
@@ -62,6 +72,7 @@ namespace Invercargill {
             else {
                 add_mapping(new PropertyMapping<T>() {
                     name = name,
+                    mandatory = mandatory,
                     getter = (o) => new NativeElement<TProp>(getter(o)),
                     setter = (o,d) => setter(o, d.as<TProp>())
                 });
@@ -69,38 +80,37 @@ namespace Invercargill {
             return this;
         }
 
-        public PropertyMapperBuilder<T> map_with<TObj>(string name, owned PropertyGetter<T, TObj> getter, owned PropertySetter<T, TObj> setter, PropertyMapper<TObj> mapper) {
+        public PropertyMapperBuilder<T> map_with<TObj>(string name, owned PropertyGetter<T, TObj> getter, owned PropertySetter<T, TObj> setter, PropertyMapper<TObj> mapper, bool mandatory = true) {
             add_mapping(new PropertyMapping<T>() {
                 name = name,
+                mandatory = mandatory,
                 getter = (o) => new NativeElement<Properties>(mapper.map_from(getter(o))),
                 setter = (o,d) => setter(o, mapper.materialise(d.as<Properties>()))
             });
             return this;
         }
 
-        public PropertyMapperBuilder<T> map_collection<TCollection, TObj>(string name, owned PropertyGetter<T, Collection<TObj>> getter, owned PropertySetter<T, TCollection<TObj>> setter) requires (typeof(TCollection).is_a(typeof(Collection))) {
+        public PropertyMapperBuilder<T> map_many<TObj>(string name, owned PropertyGetter<T, Enumerable<TObj>> getter, owned PropertySetter<T, Enumerable<TObj>> setter, bool mandatory = true) {
             add_mapping(new PropertyMapping<T>() {
                 name = name,
+                mandatory = mandatory,
                 getter = (o) => new NativeElement<Elements>(getter(o).to_elements()),
-                setter = (o,d) => {
-                    var collection = (Collection)Object.new(typeof(TCollection));
-                    collection.add_all(d.as<Elements>().elements_as<TObj>());
-                    setter(o, collection);
-                }
+                setter = (o,d) => setter(o, d.as<Elements>().elements_as<TObj>())
             });
             return this;
         }
 
-        public PropertyMapperBuilder<T> map_collection_with<TCollection, TObj>(string name, owned PropertyGetter<T, Collection<TObj>> getter, owned PropertySetter<T, TCollection<TObj>> setter, PropertyMapper<TObj> mapper) requires (typeof(TCollection).is_a(typeof(Collection))) {
+        public PropertyMapperBuilder<T> map_many_with<TObj>(string name, owned PropertyGetter<T, Enumerable<TObj>> getter, owned PropertySetter<T, Enumerable<TObj>> setter, PropertyMapper<TObj> mapper, bool mandatory = true) {
             add_mapping(new PropertyMapping<T>() {
                 name = name,
+                mandatory = mandatory,
                 getter = (o) => new NativeElement<Elements>(getter(o).select<Properties>(i => mapper.map_from(i)).to_elements()),
                 setter = (o,d) => {
-                    var collection = (Collection<TObj>)Object.new(typeof(TCollection));
+                    var collection = new Series<TObj>();
                     foreach (var properties in d.as<Elements>().elements_as<Properties>()) {
                         collection.add(mapper.materialise(properties));
                     }
-                    setter(o, collection);
+                    setter(o, collection.seal());
                 }
             });
             return this;

+ 31 - 0
src/lib/Queries/From.vala

@@ -0,0 +1,31 @@
+namespace Invercargill {
+
+    private class FromQuery<T> : BaseQuery<T, T> {
+
+        private PredicateDelegate<T> predicate_func;
+
+        public FromQuery(Enumerable<T> input, owned PredicateDelegate<T> func) {
+            this.input = input;
+            predicate_func = (owned)func;
+        }
+
+        public override Tracker<T> get_tracker() {
+            var tracker = input.get_tracker();
+            var condition_met = false;
+
+            return new AdvanceTracker<T>((out obj) => {
+                obj = null;
+                do {
+                    if(!tracker.has_next()) {
+                        obj = null;
+                        return false;
+                    }
+                    obj = tracker.get_next ();
+                } while(!condition_met && !predicate_func(obj));
+                condition_met = true;
+                return true;
+            });
+        }
+    }
+
+}

+ 33 - 0
src/lib/Queries/Until.vala

@@ -0,0 +1,33 @@
+namespace Invercargill {
+
+    private class UntilQuery<T> : BaseQuery<T, T> {
+
+        private PredicateDelegate<T> predicate_func;
+
+        public UntilQuery(Enumerable<T> input, owned PredicateDelegate<T> func) {
+            this.input = input;
+            predicate_func = (owned)func;
+        }
+
+        public override Tracker<T> get_tracker() {
+            var tracker = input.get_tracker();
+            var condition_met = false;
+
+            return new AdvanceTracker<T>((out obj) => {
+                obj = null;
+                if(!tracker.has_next() || condition_met) {
+                    return false;
+                }
+
+                obj = tracker.get_next ();
+                if(predicate_func(obj)) {
+                    condition_met = true;
+                    obj = null;
+                    return false;
+                }
+                return true;
+            });
+        }
+    }
+
+}

+ 2 - 0
src/lib/meson.build

@@ -36,6 +36,8 @@ sources += files('Queries/Parallel.vala')
 sources += files('Queries/Unique.vala')
 sources += files('Queries/Position.vala')
 sources += files('Queries/FilterTransform.vala')
+sources += files('Queries/From.vala')
+sources += files('Queries/Until.vala')
 
 sources += files('Concrete/ArrayEnumerable.vala')
 sources += files('Concrete/GeeEnumerable.vala')