mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 01:43:36 +01:00
cln-plugin: add multi options for String and i64
Changelog-Added: cln-plugin: add multi options for String and i64
This commit is contained in:
parent
88504ea6d2
commit
7ffd0a3936
@ -3,10 +3,11 @@
|
||||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
use cln_plugin::options::{
|
||||
self, BooleanConfigOption, DefaultIntegerConfigOption, IntegerConfigOption,
|
||||
self, BooleanConfigOption, DefaultIntegerArrayConfigOption, DefaultIntegerConfigOption,
|
||||
DefaultStringArrayConfigOption, IntegerArrayConfigOption, IntegerConfigOption,
|
||||
StringArrayConfigOption,
|
||||
};
|
||||
use cln_plugin::{messages, Builder, Error, Plugin};
|
||||
use tokio;
|
||||
|
||||
const TEST_NOTIF_TAG: &str = "test_custom_notification";
|
||||
|
||||
@ -19,6 +20,32 @@ const TEST_OPTION: DefaultIntegerConfigOption = DefaultIntegerConfigOption::new_
|
||||
const TEST_OPTION_NO_DEFAULT: IntegerConfigOption =
|
||||
IntegerConfigOption::new_i64_no_default("opt-option", "An option without a default");
|
||||
|
||||
const TEST_MULTI_STR_OPTION: StringArrayConfigOption =
|
||||
StringArrayConfigOption::new_str_arr_no_default(
|
||||
"multi-str-option",
|
||||
"An option that can have multiple string values",
|
||||
);
|
||||
|
||||
const TEST_MULTI_STR_OPTION_DEFAULT: DefaultStringArrayConfigOption =
|
||||
DefaultStringArrayConfigOption::new_str_arr_with_default(
|
||||
"multi-str-option-default",
|
||||
"Default1",
|
||||
"An option that can have multiple string values with defaults",
|
||||
);
|
||||
|
||||
const TEST_MULTI_I64_OPTION: IntegerArrayConfigOption =
|
||||
IntegerArrayConfigOption::new_i64_arr_no_default(
|
||||
"multi-i64-option",
|
||||
"An option that can have multiple i64 values",
|
||||
);
|
||||
|
||||
const TEST_MULTI_I64_OPTION_DEFAULT: DefaultIntegerArrayConfigOption =
|
||||
DefaultIntegerArrayConfigOption::new_i64_arr_with_default(
|
||||
"multi-i64-option-default",
|
||||
-42,
|
||||
"An option that can have multiple i64 values with defaults",
|
||||
);
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), anyhow::Error> {
|
||||
let state = ();
|
||||
@ -33,6 +60,10 @@ async fn main() -> Result<(), anyhow::Error> {
|
||||
.option(TEST_OPTION)
|
||||
.option(TEST_OPTION_NO_DEFAULT)
|
||||
.option(test_dynamic_option)
|
||||
.option(TEST_MULTI_STR_OPTION)
|
||||
.option(TEST_MULTI_STR_OPTION_DEFAULT)
|
||||
.option(TEST_MULTI_I64_OPTION)
|
||||
.option(TEST_MULTI_I64_OPTION_DEFAULT)
|
||||
.setconfig_callback(setconfig_callback)
|
||||
.rpcmethod("testmethod", "This is a test", testmethod)
|
||||
.rpcmethod(
|
||||
@ -79,10 +110,18 @@ async fn setconfig_callback(
|
||||
async fn testoptions(p: Plugin<()>, _v: serde_json::Value) -> Result<serde_json::Value, Error> {
|
||||
let test_option = p.option(&TEST_OPTION)?;
|
||||
let test_option_no_default = p.option(&TEST_OPTION_NO_DEFAULT)?;
|
||||
let test_multi_str_option = p.option(&TEST_MULTI_STR_OPTION)?;
|
||||
let test_multi_str_option_default = p.option(&TEST_MULTI_STR_OPTION_DEFAULT)?;
|
||||
let test_multi_i64_option = p.option(&TEST_MULTI_I64_OPTION)?;
|
||||
let test_multi_i64_option_default = p.option(&TEST_MULTI_I64_OPTION_DEFAULT)?;
|
||||
|
||||
Ok(json!({
|
||||
"test-option": test_option,
|
||||
"opt-option" : test_option_no_default
|
||||
"opt-option" : test_option_no_default,
|
||||
"multi-str-option": test_multi_str_option,
|
||||
"multi-str-option-default": test_multi_str_option_default,
|
||||
"multi-i64-option": test_multi_i64_option,
|
||||
"multi-i64-option-default": test_multi_i64_option_default,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -437,6 +437,15 @@ where
|
||||
let option_value: Option<options::Value> = match (json_value, default_value) {
|
||||
(None, None) => None,
|
||||
(None, Some(default)) => Some(default.clone()),
|
||||
(Some(JValue::Array(a)), _) => match a.first() {
|
||||
Some(JValue::String(_)) => Some(OValue::StringArray(
|
||||
a.iter().map(|x| x.as_str().unwrap().to_string()).collect(),
|
||||
)),
|
||||
Some(JValue::Number(_)) => Some(OValue::IntegerArray(
|
||||
a.iter().map(|x| x.as_i64().unwrap()).collect(),
|
||||
)),
|
||||
_ => panic!("Array type not supported for option: {}", name),
|
||||
},
|
||||
(Some(JValue::String(s)), _) => Some(OValue::String(s.to_string())),
|
||||
(Some(JValue::Number(i)), _) => Some(OValue::Integer(i.as_i64().unwrap())),
|
||||
(Some(JValue::Bool(b)), _) => Some(OValue::Boolean(*b)),
|
||||
|
@ -77,6 +77,7 @@
|
||||
//! description : "A config option of type string that takes no default",
|
||||
//! deprecated : false, // Option is not deprecated
|
||||
//! dynamic: false, //Option is not dynamic
|
||||
//! multi: false, //Option must not be multi, use StringArray instead
|
||||
//! };
|
||||
//! ```
|
||||
//!
|
||||
@ -131,7 +132,7 @@
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
use serde::ser::Serializer;
|
||||
use serde::ser::{SerializeSeq, Serializer};
|
||||
use serde::Serialize;
|
||||
|
||||
pub mod config_type {
|
||||
@ -140,10 +141,18 @@ pub mod config_type {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DefaultInteger;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IntegerArray;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DefaultIntegerArray;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct String;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DefaultString;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct StringArray;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DefaultStringArray;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Boolean;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DefaultBoolean;
|
||||
@ -153,14 +162,22 @@ pub mod config_type {
|
||||
|
||||
/// Config values are represented as an i64. No default is used
|
||||
pub type IntegerConfigOption<'a> = ConfigOption<'a, config_type::Integer>;
|
||||
// Config values are represented as a Vec<i64>. No default is used.
|
||||
pub type IntegerArrayConfigOption<'a> = ConfigOption<'a, config_type::IntegerArray>;
|
||||
/// Config values are represented as a String. No default is used.
|
||||
pub type StringConfigOption<'a> = ConfigOption<'a, config_type::String>;
|
||||
// Config values are represented as a Vec<String>. No default is used.
|
||||
pub type StringArrayConfigOption<'a> = ConfigOption<'a, config_type::StringArray>;
|
||||
/// Config values are represented as a boolean. No default is used.
|
||||
pub type BooleanConfigOption<'a> = ConfigOption<'a, config_type::Boolean>;
|
||||
/// Config values are repsentedas an i64. A default is used
|
||||
pub type DefaultIntegerConfigOption<'a> = ConfigOption<'a, config_type::DefaultInteger>;
|
||||
// Config values are represented as a Vec<i64>. A default is used
|
||||
pub type DefaultIntegerArrayConfigOption<'a> = ConfigOption<'a, config_type::DefaultIntegerArray>;
|
||||
/// Config values are repsentedas an String. A default is used
|
||||
pub type DefaultStringConfigOption<'a> = ConfigOption<'a, config_type::DefaultString>;
|
||||
// Config values are represented as a Vec<String>. A default is used
|
||||
pub type DefaultStringArrayConfigOption<'a> = ConfigOption<'a, config_type::DefaultStringArray>;
|
||||
/// Config values are repsentedas an bool. A default is used
|
||||
pub type DefaultBooleanConfigOption<'a> = ConfigOption<'a, config_type::DefaultBoolean>;
|
||||
/// Config value is represented as a flag
|
||||
@ -197,6 +214,26 @@ impl<'a> OptionType<'a> for config_type::DefaultString {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionType<'a> for config_type::DefaultStringArray {
|
||||
type OutputValue = Vec<String>;
|
||||
type DefaultValue = &'a str;
|
||||
|
||||
fn convert_default(value: &Self::DefaultValue) -> Option<Value> {
|
||||
Some(Value::String(value.to_string()))
|
||||
}
|
||||
|
||||
fn from_value(value: &Option<Value>) -> Self::OutputValue {
|
||||
match value {
|
||||
Some(Value::StringArray(s)) => s.clone(),
|
||||
_ => panic!("Type mismatch. Expected string-array but found {:?}", value),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_value_type() -> ValueType {
|
||||
ValueType::String
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionType<'a> for config_type::DefaultInteger {
|
||||
type OutputValue = i64;
|
||||
type DefaultValue = i64;
|
||||
@ -205,7 +242,7 @@ impl<'a> OptionType<'a> for config_type::DefaultInteger {
|
||||
Some(Value::Integer(*value))
|
||||
}
|
||||
|
||||
fn from_value(value: &Option<Value>) -> i64 {
|
||||
fn from_value(value: &Option<Value>) -> Self::OutputValue {
|
||||
match value {
|
||||
Some(Value::Integer(i)) => *i,
|
||||
_ => panic!("Type mismatch. Expected Integer but found {:?}", value),
|
||||
@ -217,6 +254,29 @@ impl<'a> OptionType<'a> for config_type::DefaultInteger {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionType<'a> for config_type::DefaultIntegerArray {
|
||||
type OutputValue = Vec<i64>;
|
||||
type DefaultValue = i64;
|
||||
|
||||
fn convert_default(value: &Self::DefaultValue) -> Option<Value> {
|
||||
Some(Value::Integer(*value))
|
||||
}
|
||||
|
||||
fn from_value(value: &Option<Value>) -> Self::OutputValue {
|
||||
match value {
|
||||
Some(Value::IntegerArray(i)) => i.clone(),
|
||||
_ => panic!(
|
||||
"Type mismatch. Expected Integer-array but found {:?}",
|
||||
value
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_value_type() -> ValueType {
|
||||
ValueType::Integer
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionType<'a> for config_type::DefaultBoolean {
|
||||
type OutputValue = bool;
|
||||
type DefaultValue = bool;
|
||||
@ -224,7 +284,7 @@ impl<'a> OptionType<'a> for config_type::DefaultBoolean {
|
||||
fn convert_default(value: &bool) -> Option<Value> {
|
||||
Some(Value::Boolean(*value))
|
||||
}
|
||||
fn from_value(value: &Option<Value>) -> bool {
|
||||
fn from_value(value: &Option<Value>) -> Self::OutputValue {
|
||||
match value {
|
||||
Some(Value::Boolean(b)) => *b,
|
||||
_ => panic!("Type mismatch. Expected Boolean but found {:?}", value),
|
||||
@ -244,7 +304,7 @@ impl<'a> OptionType<'a> for config_type::Flag {
|
||||
Some(Value::Boolean(false))
|
||||
}
|
||||
|
||||
fn from_value(value: &Option<Value>) -> bool {
|
||||
fn from_value(value: &Option<Value>) -> Self::OutputValue {
|
||||
match value {
|
||||
Some(Value::Boolean(b)) => *b,
|
||||
_ => panic!("Type mismatch. Expected Boolean but found {:?}", value),
|
||||
@ -264,7 +324,7 @@ impl<'a> OptionType<'a> for config_type::String {
|
||||
None
|
||||
}
|
||||
|
||||
fn from_value(value: &Option<Value>) -> Option<String> {
|
||||
fn from_value(value: &Option<Value>) -> Self::OutputValue {
|
||||
match value {
|
||||
Some(Value::String(s)) => Some(s.to_string()),
|
||||
None => None,
|
||||
@ -280,6 +340,30 @@ impl<'a> OptionType<'a> for config_type::String {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionType<'a> for config_type::StringArray {
|
||||
type OutputValue = Option<Vec<String>>;
|
||||
type DefaultValue = ();
|
||||
|
||||
fn convert_default(_value: &()) -> Option<Value> {
|
||||
None
|
||||
}
|
||||
|
||||
fn from_value(value: &Option<Value>) -> Self::OutputValue {
|
||||
match value {
|
||||
Some(Value::StringArray(s)) => Some(s.clone()),
|
||||
None => None,
|
||||
_ => panic!(
|
||||
"Type mismatch. Expected Option<Vec<String>> but found {:?}",
|
||||
value
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_value_type() -> ValueType {
|
||||
ValueType::String
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionType<'a> for config_type::Integer {
|
||||
type OutputValue = Option<i64>;
|
||||
type DefaultValue = ();
|
||||
@ -303,6 +387,31 @@ impl<'a> OptionType<'a> for config_type::Integer {
|
||||
ValueType::Integer
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionType<'a> for config_type::IntegerArray {
|
||||
type OutputValue = Option<Vec<i64>>;
|
||||
type DefaultValue = ();
|
||||
|
||||
fn convert_default(_value: &()) -> Option<Value> {
|
||||
None
|
||||
}
|
||||
|
||||
fn from_value(value: &Option<Value>) -> Self::OutputValue {
|
||||
match value {
|
||||
Some(Value::IntegerArray(i)) => Some(i.clone()),
|
||||
None => None,
|
||||
_ => panic!(
|
||||
"Type mismatch. Expected Option<Vec<Integer>> but found {:?}",
|
||||
value
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_value_type() -> ValueType {
|
||||
ValueType::Integer
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OptionType<'a> for config_type::Boolean {
|
||||
type OutputValue = Option<bool>;
|
||||
type DefaultValue = ();
|
||||
@ -343,6 +452,8 @@ pub enum Value {
|
||||
String(String),
|
||||
Integer(i64),
|
||||
Boolean(bool),
|
||||
StringArray(Vec<String>),
|
||||
IntegerArray(Vec<i64>),
|
||||
}
|
||||
|
||||
impl Serialize for Value {
|
||||
@ -354,6 +465,20 @@ impl Serialize for Value {
|
||||
Value::String(s) => serializer.serialize_str(s),
|
||||
Value::Integer(i) => serializer.serialize_i64(*i),
|
||||
Value::Boolean(b) => serializer.serialize_bool(*b),
|
||||
Value::StringArray(sa) => {
|
||||
let mut seq = serializer.serialize_seq(Some(sa.len()))?;
|
||||
for element in sa {
|
||||
seq.serialize_element(element)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
Value::IntegerArray(sa) => {
|
||||
let mut seq = serializer.serialize_seq(Some(sa.len()))?;
|
||||
for element in sa {
|
||||
seq.serialize_element(element)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -374,6 +499,8 @@ impl Value {
|
||||
Value::String(s) => Some(&s),
|
||||
Value::Integer(_) => None,
|
||||
Value::Boolean(_) => None,
|
||||
Value::StringArray(_) => None,
|
||||
Value::IntegerArray(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,6 +538,40 @@ impl Value {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the `Value` is a Vec<String>. Returns false otherwise.
|
||||
///
|
||||
/// For any Value on which `is_str_arr` returns true, `as_str_arr` is
|
||||
/// guaranteed to return the Vec<String> value.
|
||||
pub fn is_str_arr(&self) -> bool {
|
||||
self.as_str_arr().is_some()
|
||||
}
|
||||
|
||||
/// If the `Value` is a Vec<String>, returns the associated Vec<String>.
|
||||
/// Returns None otherwise.
|
||||
pub fn as_str_arr(&self) -> Option<&Vec<String>> {
|
||||
match self {
|
||||
Value::StringArray(sa) => Some(sa),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the `Value` is a Vec<i64>. Returns false otherwise.
|
||||
///
|
||||
/// For any Value on which `is_i64_arr` returns true, `as_i64_arr` is
|
||||
/// guaranteed to return the Vec<i64> value.
|
||||
pub fn is_i64_arr(&self) -> bool {
|
||||
self.as_i64_arr().is_some()
|
||||
}
|
||||
|
||||
/// If the `Value` is a Vec<i64>, returns the associated Vec<i64>.
|
||||
/// Returns None otherwise.
|
||||
pub fn as_i64_arr(&self) -> Option<&Vec<i64>> {
|
||||
match self {
|
||||
Value::IntegerArray(sa) => Some(sa),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -422,6 +583,7 @@ pub struct ConfigOption<'a, V: OptionType<'a>> {
|
||||
pub description: &'a str,
|
||||
pub deprecated: bool,
|
||||
pub dynamic: bool,
|
||||
pub multi: bool,
|
||||
}
|
||||
|
||||
impl<'a, V: OptionType<'a>> ConfigOption<'a, V> {
|
||||
@ -433,6 +595,7 @@ impl<'a, V: OptionType<'a>> ConfigOption<'a, V> {
|
||||
description: self.description.to_string(),
|
||||
deprecated: self.deprecated,
|
||||
dynamic: self.dynamic,
|
||||
multi: self.multi,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -449,6 +612,7 @@ impl<'a> DefaultStringConfigOption<'a> {
|
||||
description: description,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: false,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
@ -465,6 +629,45 @@ impl<'a> StringConfigOption<'a> {
|
||||
description: description,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: false,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
self.dynamic = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DefaultStringArrayConfigOption<'a> {
|
||||
pub const fn new_str_arr_with_default(
|
||||
name: &'a str,
|
||||
default: &'a str,
|
||||
description: &'a str,
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
default,
|
||||
description,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: true,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
self.dynamic = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> StringArrayConfigOption<'a> {
|
||||
pub const fn new_str_arr_no_default(name: &'a str, description: &'a str) -> Self {
|
||||
Self {
|
||||
name,
|
||||
default: (),
|
||||
description,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: true,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
@ -481,6 +684,7 @@ impl<'a> DefaultIntegerConfigOption<'a> {
|
||||
description: description,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: false,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
@ -497,6 +701,45 @@ impl<'a> IntegerConfigOption<'a> {
|
||||
description: description,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: false,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
self.dynamic = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DefaultIntegerArrayConfigOption<'a> {
|
||||
pub const fn new_i64_arr_with_default(
|
||||
name: &'a str,
|
||||
default: i64,
|
||||
description: &'a str,
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
default,
|
||||
description,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: true,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
self.dynamic = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntegerArrayConfigOption<'a> {
|
||||
pub const fn new_i64_arr_no_default(name: &'a str, description: &'a str) -> Self {
|
||||
Self {
|
||||
name,
|
||||
default: (),
|
||||
description,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: true,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
@ -513,6 +756,7 @@ impl<'a> BooleanConfigOption<'a> {
|
||||
default: (),
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: false,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
@ -529,6 +773,7 @@ impl<'a> DefaultBooleanConfigOption<'a> {
|
||||
default: default,
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: false,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
@ -545,6 +790,7 @@ impl<'a> FlagConfigOption<'a> {
|
||||
default: (),
|
||||
deprecated: false,
|
||||
dynamic: false,
|
||||
multi: false,
|
||||
}
|
||||
}
|
||||
pub fn dynamic(mut self) -> Self {
|
||||
@ -569,6 +815,7 @@ pub struct UntypedConfigOption {
|
||||
#[serde(skip_serializing_if = "is_false")]
|
||||
deprecated: bool,
|
||||
dynamic: bool,
|
||||
multi: bool,
|
||||
}
|
||||
|
||||
impl UntypedConfigOption {
|
||||
@ -613,6 +860,7 @@ mod test {
|
||||
"default": "default",
|
||||
"type": "string",
|
||||
"dynamic": false,
|
||||
"multi": false,
|
||||
}),
|
||||
),
|
||||
(
|
||||
@ -623,6 +871,7 @@ mod test {
|
||||
"default": 42,
|
||||
"type": "int",
|
||||
"dynamic": false,
|
||||
"multi": false,
|
||||
}),
|
||||
),
|
||||
(
|
||||
@ -637,6 +886,7 @@ mod test {
|
||||
"default": true,
|
||||
"type": "bool",
|
||||
"dynamic": true,
|
||||
"multi": false,
|
||||
}),
|
||||
),
|
||||
(
|
||||
@ -647,6 +897,29 @@ mod test {
|
||||
"type" : "flag",
|
||||
"default" : false,
|
||||
"dynamic": false,
|
||||
"multi": false,
|
||||
}),
|
||||
),
|
||||
(
|
||||
ConfigOption::new_str_arr_with_default("name", "Default1", "description").build(),
|
||||
json!({
|
||||
"name" : "name",
|
||||
"description": "description",
|
||||
"type" : "string",
|
||||
"default" : "Default1",
|
||||
"dynamic": false,
|
||||
"multi": true,
|
||||
}),
|
||||
),
|
||||
(
|
||||
ConfigOption::new_i64_arr_with_default("name", -46, "description").build(),
|
||||
json!({
|
||||
"name" : "name",
|
||||
"description": "description",
|
||||
"type" : "int",
|
||||
"default" : -46,
|
||||
"dynamic": false,
|
||||
"multi": true,
|
||||
}),
|
||||
),
|
||||
];
|
||||
|
@ -74,16 +74,34 @@ def test_plugin_options_handle_defaults(node_factory):
|
||||
"""Start a minimal plugin and ensure it is well-behaved
|
||||
"""
|
||||
bin_path = Path.cwd() / "target" / RUST_PROFILE / "examples" / "cln-plugin-startup"
|
||||
l1 = node_factory.get_node(options={"plugin": str(bin_path), 'opt-option': 31337, "test-option": 31338})
|
||||
l1 = node_factory.get_node(
|
||||
options={
|
||||
"plugin": str(bin_path),
|
||||
"opt-option": 31337,
|
||||
"test-option": 31338,
|
||||
"multi-str-option": ["String1", "String2"],
|
||||
"multi-str-option-default": ["NotDefault1", "NotDefault2"],
|
||||
"multi-i64-option": [1, 2, 3, 4],
|
||||
"multi-i64-option-default": [5, 6],
|
||||
}
|
||||
)
|
||||
opts = l1.rpc.testoptions()
|
||||
assert opts["opt-option"] == 31337
|
||||
assert opts["test-option"] == 31338
|
||||
assert opts["multi-str-option"] == ["String1", "String2"]
|
||||
assert opts["multi-str-option-default"] == ["NotDefault1", "NotDefault2"]
|
||||
assert opts["multi-i64-option"] == [1, 2, 3, 4]
|
||||
assert opts["multi-i64-option-default"] == [5, 6]
|
||||
|
||||
# Do not set any value, should be None now
|
||||
l1 = node_factory.get_node(options={"plugin": str(bin_path)})
|
||||
opts = l1.rpc.testoptions()
|
||||
assert opts["opt-option"] is None, "opt-option has no default"
|
||||
assert opts["test-option"] == 42, "test-option has a default of 42"
|
||||
assert opts["multi-str-option"] is None
|
||||
assert opts["multi-str-option-default"] == ["Default1"]
|
||||
assert opts["multi-i64-option"] is None
|
||||
assert opts["multi-i64-option-default"] == [-42]
|
||||
|
||||
|
||||
def test_grpc_connect(node_factory):
|
||||
|
Loading…
Reference in New Issue
Block a user