mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 07:34:24 +01:00
msggen: Add parser for "oneOf"
This commit is contained in:
committed by
Rusty Russell
parent
c1ee32027d
commit
1f40db3594
@@ -133,18 +133,21 @@ class CompositeField(Field):
|
|||||||
logger.warning(f"Unmanaged {fpath}, it is deprecated")
|
logger.warning(f"Unmanaged {fpath}, it is deprecated")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if "type" not in ftype:
|
if 'oneOf' in ftype:
|
||||||
|
field = UnionField.from_js(ftype, fpath)
|
||||||
|
|
||||||
|
elif "type" not in ftype:
|
||||||
logger.warning(f"Unmanaged {fpath}, it doesn't have a type")
|
logger.warning(f"Unmanaged {fpath}, it doesn't have a type")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
elif ftype["type"] == ["string", "null"]:
|
||||||
# TODO Remove the `['string', 'null']` match once
|
# TODO Remove the `['string', 'null']` match once
|
||||||
# `listpeers.peers[].channels[].closer` no longer has this
|
# `listpeers.peers[].channels[].closer` no longer has this
|
||||||
# type
|
# type
|
||||||
if ftype["type"] == ["string", "null"]:
|
|
||||||
ftype["type"] = "string"
|
ftype["type"] = "string"
|
||||||
|
|
||||||
# Peek into the type so we know how to decode it
|
# Peek into the type so we know how to decode it
|
||||||
if ftype["type"] in ["string", ["string", "null"]] and "enum" in ftype:
|
elif ftype["type"] in ["string", ["string", "null"]] and "enum" in ftype:
|
||||||
field = EnumField.from_js(ftype, fpath)
|
field = EnumField.from_js(ftype, fpath)
|
||||||
|
|
||||||
elif ftype["type"] == "object":
|
elif ftype["type"] == "object":
|
||||||
@@ -210,6 +213,39 @@ class EnumField(Field):
|
|||||||
values = ",".join([v for v in self.values if v is not None])
|
values = ",".join([v for v in self.values if v is not None])
|
||||||
return f"Enum[path={self.path}, required={self.required}, values=[{values}]]"
|
return f"Enum[path={self.path}, required={self.required}, values=[{values}]]"
|
||||||
|
|
||||||
|
class UnionField(Field):
|
||||||
|
"""A type that can be one of a number of types.
|
||||||
|
|
||||||
|
Corresponds to the `oneOf` type in JSON-Schema, an `enum` in Rust
|
||||||
|
and a `oneof` in protobuf.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, path, description, variants):
|
||||||
|
Field.__init__(self, path, description)
|
||||||
|
self.variants = variants
|
||||||
|
self.typename = path2type(path)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_js(cls, js, path):
|
||||||
|
assert('oneOf' in js)
|
||||||
|
variants = []
|
||||||
|
for child_js in js['oneOf']:
|
||||||
|
if child_js["type"] == "object":
|
||||||
|
itemtype = CompositeField.from_js(child_js, path)
|
||||||
|
|
||||||
|
elif child_js["type"] == "string" and "enum" in child_js:
|
||||||
|
itemtype = EnumField.from_js(child_js, path)
|
||||||
|
|
||||||
|
elif child_js["type"] in PrimitiveField.types:
|
||||||
|
itemtype = PrimitiveField(
|
||||||
|
child_js["type"], path, child_js.get("description", "")
|
||||||
|
)
|
||||||
|
elif child_js["type"] == "array":
|
||||||
|
itemtype = ArrayField.from_js(path, child_js)
|
||||||
|
variants.append(itemtype)
|
||||||
|
|
||||||
|
return UnionField(path, js.get('description', None), variants)
|
||||||
|
|
||||||
|
|
||||||
class PrimitiveField(Field):
|
class PrimitiveField(Field):
|
||||||
# Leaf types that we expect the binding languages to provide
|
# Leaf types that we expect the binding languages to provide
|
||||||
@@ -228,13 +264,15 @@ class PrimitiveField(Field):
|
|||||||
"msat|all",
|
"msat|all",
|
||||||
"hex",
|
"hex",
|
||||||
"short_channel_id",
|
"short_channel_id",
|
||||||
|
"short_channel_id_dir",
|
||||||
"txid",
|
"txid",
|
||||||
"integer",
|
"integer",
|
||||||
|
"outpoint",
|
||||||
"u16",
|
"u16",
|
||||||
"number",
|
"number",
|
||||||
"feerate",
|
"feerate",
|
||||||
"utxo", # A string representing the tuple (txid, outnum)
|
"utxo", # A string representing the tuple (txid, outnum)
|
||||||
"OutputDesc", # A dict that maps an address to an amount (bitcoind style)
|
"outputdesc", # A dict that maps an address to an amount (bitcoind style)
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, typename, path, description):
|
def __init__(self, typename, path, description):
|
||||||
@@ -257,12 +295,16 @@ class ArrayField(Field):
|
|||||||
# Determine how nested we are
|
# Determine how nested we are
|
||||||
dims = 1
|
dims = 1
|
||||||
child_js = js["items"]
|
child_js = js["items"]
|
||||||
while child_js["type"] == "array":
|
while child_js.get("type", None) == "array":
|
||||||
dims += 1
|
dims += 1
|
||||||
child_js = child_js["items"]
|
child_js = child_js["items"]
|
||||||
|
|
||||||
path += "[]" * dims
|
path += "[]" * dims
|
||||||
if child_js["type"] == "object":
|
if 'oneOf' in child_js:
|
||||||
|
assert('type' not in child_js)
|
||||||
|
itemtype = UnionField.from_js(child_js, path)
|
||||||
|
|
||||||
|
elif child_js["type"] == "object":
|
||||||
itemtype = CompositeField.from_js(child_js, path)
|
itemtype = CompositeField.from_js(child_js, path)
|
||||||
|
|
||||||
elif child_js["type"] == "string" and "enum" in child_js:
|
elif child_js["type"] == "string" and "enum" in child_js:
|
||||||
|
|||||||
Reference in New Issue
Block a user