about summary refs log tree commit diff
path: root/universe/ac_types/parse.py
diff options
context:
space:
mode:
Diffstat (limited to 'universe/ac_types/parse.py')
-rw-r--r--universe/ac_types/parse.py138
1 files changed, 138 insertions, 0 deletions
diff --git a/universe/ac_types/parse.py b/universe/ac_types/parse.py
new file mode 100644
index 000000000000..872f3f0c3fcc
--- /dev/null
+++ b/universe/ac_types/parse.py
@@ -0,0 +1,138 @@
+import re
+import string
+from test_utils import simple_assert
+
+
+def if_empty(x, parser):
+    """If the field is empty, use `x`, otherwise, call `parser` on it."""
+    def fn(y):
+        if y == "":
+            return x
+        else:
+            return parser(y)
+
+    return fn
+
+
+# nullable :: Parser -> Parser
+def nullable(parser):
+    def fn(x):
+        if x == "":
+            return None
+        else:
+            return parser(x)
+
+    return fn
+
+
+def required(column_name, parser):
+    def fn(x):
+        if x == "":
+            raise Exception(
+                "\"{}\" is a required field and cannot be empty".format(
+                    column_name))
+        else:
+            return parser(x)
+
+    return fn
+
+
+def apply_parser(parser, row):
+    """Calls each value in `parser` on the corresponding field in the
+    dictionary, `row`."""
+    result = {}
+    for k, fn in parser.items():
+        result[k] = fn(row[k])
+    return result
+
+
+def raise_parse_error(x, expected):
+    """Raises a generic `Exception` when `x` is not a member of the `expected`
+    set."""
+    raise Exception("\"{}\" is none of the following: \"{}\"".format(
+        x, ", ".join(expected)))
+
+
+def as_hours(x):
+    match = re.search(r'(\d+) hours', x)
+    if match:
+        try:
+            return int(match[1])
+        except:
+            raise Exception('Failed to parse {} as an int'.format(match[1]))
+    else:
+        raise Exception('Failed to parse {} as hours'.format(x))
+
+
+actual = as_hours('24 hours')
+expected = 24
+simple_assert(actual, expected, name='as_hours')
+
+
+def as_mapping(mapping):
+    def fn(x):
+        if mapping[x]:
+            return mapping[x]
+        else:
+            raise_parse_error(x, set(mapping.keys()))
+
+    return fn
+
+
+# as_yes_no :: String -> Boolean
+def as_yes_no(x):
+    """Attempt to parse `x`, a Yes or No value, into a boolean."""
+    if x == "Yes":
+        return True
+    elif x == "No":
+        return False
+    else:
+        raise_parse_error(x, {"Yes", "No"})
+
+
+# as_data_source_type :: String -> String
+def as_data_source_type(x):
+    """Attempt to parse `x` as the Data Source Type column, which is an enum
+    defined in the go/consult-types-authwf-auto-consult sheet."""
+    acceptable = {"Hard-Code", "N/A", "Atlas", "Form"}
+    if x not in acceptable:
+        raise_parse_error(x, acceptable)
+    return x
+
+
+# as_type :: String -> String
+def as_type(x):
+    """Attempt to parse `x` as the Type column, which is an enum defined in the
+    go/consult-types-authwf-auto-consult sheet."""
+    acceptable = {
+        "Parent Routing FRD", "Consult Parameter", "Consult Routing FRD",
+        "Input", "Return Routing FRD"
+    }
+    if x not in acceptable:
+        raise_parse_error(x, acceptable)
+    return x
+
+
+def as_int(x):
+    return int(x)
+
+
+def as_union_type(x):
+    if " or " in x:
+        return [string.trim_surrounding('"', x) for x in x.split(" or ")]
+    else:
+        return [x]
+
+
+simple_assert(as_union_type('Non-Union'), ['Non-Union'], name='as_union_type')
+
+simple_assert(as_union_type(
+    '"Germany" or "Netherlands" or "Spain" or "Check Republic" or "United Kingdom"'
+), ['Germany', 'Netherlands', 'Spain', 'Check Republic', 'United Kingdom'],
+              name='as_union_type')
+
+
+# identity :: a -> a
+def identity(x):
+    """Returns `x` unchanged."""
+    return x