diff --git a/contrib/msggen/msggen/gen/grpc/convert.py b/contrib/msggen/msggen/gen/grpc/convert.py index 72178b31e..3adc7978c 100644 --- a/contrib/msggen/msggen/gen/grpc/convert.py +++ b/contrib/msggen/msggen/gen/grpc/convert.py @@ -130,6 +130,8 @@ class GrpcConverterGenerator(IGenerator): "TlvStream?": f"c.{name}.map(|s| s.into())", "RoutehintList?": f"c.{name}.map(|rl| rl.into())", "DecodeRoutehintList?": f"c.{name}.map(|drl| drl.into())", + "string_map": f"Some(c.{name})", + "string_map?": f"c.{name}.unwrap_or(HashMap::new())", }.get( typ, f"c.{name}" # default to just assignment ) @@ -202,6 +204,7 @@ class GrpcConverterGenerator(IGenerator): use cln_rpc::notifications; use crate::pb; use std::str::FromStr; + use std::collections::HashMap; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; use cln_rpc::primitives::PublicKey; diff --git a/contrib/msggen/msggen/gen/grpc/proto.py b/contrib/msggen/msggen/gen/grpc/proto.py index b0af147e1..3f2b981ab 100644 --- a/contrib/msggen/msggen/gen/grpc/proto.py +++ b/contrib/msggen/msggen/gen/grpc/proto.py @@ -201,7 +201,7 @@ class GrpcGenerator(IGenerator): if f.omit(): continue - opt = "optional " if f.optional else "" + opt = "optional " if f.optional and not (isinstance(f, PrimitiveField) and f.typename == "string_map") else "" if isinstance(f, ArrayField): typename = f.override( diff --git a/contrib/msggen/msggen/gen/grpc/unconvert.py b/contrib/msggen/msggen/gen/grpc/unconvert.py index 974139b60..16a7591d1 100644 --- a/contrib/msggen/msggen/gen/grpc/unconvert.py +++ b/contrib/msggen/msggen/gen/grpc/unconvert.py @@ -131,6 +131,8 @@ class GrpcUnconverterGenerator(GrpcConverterGenerator): "hash?": f"c.{name}.map(|v| Sha256::from_slice(&v).unwrap())", "txid": f"hex::encode(&c.{name})", "TlvStream?": f"c.{name}.map(|s| s.into())", + "string_map": f"c.{name}.unwrap()", + "string_map?": f"Some(c.{name})", }.get( typ, f"c.{name}" # default to just assignment ) diff --git a/contrib/msggen/msggen/gen/grpc/util.py b/contrib/msggen/msggen/gen/grpc/util.py index 2682d96b9..267691d59 100644 --- a/contrib/msggen/msggen/gen/grpc/util.py +++ b/contrib/msggen/msggen/gen/grpc/util.py @@ -35,6 +35,7 @@ typemap = { "secret": "bytes", "bip340sig": "string", "hash": "bytes", + "string_map": "map", } diff --git a/contrib/msggen/msggen/gen/rpc/rust.py b/contrib/msggen/msggen/gen/rpc/rust.py index 14beeae64..b2fa76251 100644 --- a/contrib/msggen/msggen/gen/rpc/rust.py +++ b/contrib/msggen/msggen/gen/rpc/rust.py @@ -46,6 +46,7 @@ typemap = { "secret": "Secret", "bip340sig": "String", "integer": "i64", + "string_map": "HashMap", } header = f""" @@ -306,6 +307,7 @@ class RustGenerator(IGenerator): #[allow(unused_imports)] use serde::{{Deserialize, Serialize}}; use core::fmt::Debug; + use std::collections::HashMap; use super::{IntoRequest, Request, TypedRequest}; """ ) diff --git a/contrib/msggen/msggen/model.py b/contrib/msggen/msggen/model.py index 50317abea..21b99d51b 100644 --- a/contrib/msggen/msggen/model.py +++ b/contrib/msggen/msggen/model.py @@ -432,6 +432,7 @@ class PrimitiveField(Field): "secret", "bip340sig", "hash", + "string_map", ] def __init__(self, typename, path, description, added, deprecated): diff --git a/contrib/pyln-testing/pyln/testing/fixtures.py b/contrib/pyln-testing/pyln/testing/fixtures.py index ef55ecd0a..5a439677b 100644 --- a/contrib/pyln-testing/pyln/testing/fixtures.py +++ b/contrib/pyln-testing/pyln/testing/fixtures.py @@ -411,6 +411,17 @@ def _extra_validator(is_request: bool): return True return False + def is_string_map(checker, instance): + """key, value map with strings""" + if not checker.is_type(instance, "object"): + return False + for k, v in instance.items(): + if not checker.is_type(k, "string"): + return False + if not checker.is_type(v, "string"): + return False + return True + # "msat" for request can be many forms if is_request: is_msat = is_msat_request @@ -439,6 +450,7 @@ def _extra_validator(is_request: bool): "outpoint": is_outpoint, "feerate": is_feerate, "outputdesc": is_outputdesc, + "string_map": is_string_map, }) return jsonschema.validators.extend(jsonschema.Draft7Validator,