refactor(firmware): centralize configuration and diagnostics
This commit is contained in:
1 parent
7048ed89d0
commit
387fdaad23
140 files changed
+6891
-4541
No files matched your search
@@ -1,27 +1,27 @@
|
||||
use kaptan_config::{ConfigAggregate, ConfigSection, ConfigViolation, ValidateFields};
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config::{Config, ConfigViolation};
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct Child {
|
||||
#[config(id = 1, key = "child.value", unit = "count", default = 1, range(min = 0, max = 2))]
|
||||
#[config(id = 1, key = "child.value", unit = "count", range(min = 0, max = 2))]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
#[config(post = Self::validate_complete)]
|
||||
struct Root {
|
||||
#[config(section)]
|
||||
child: Child,
|
||||
}
|
||||
|
||||
impl Root {
|
||||
fn validate_complete(&self) -> Result<(), ConfigViolation> {
|
||||
self.child.validate_fields()
|
||||
self.child.validate()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let root = Root::default_aggregate().unwrap();
|
||||
let root = Root {
|
||||
child: Child { value: 1 },
|
||||
};
|
||||
assert_eq!(Root::FIELD_COUNT, 1);
|
||||
assert_eq!(root.child.field_value(kaptan_config::FieldId::new(1)), Some(kaptan_config::ConfigValue::U32(1)));
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
use kaptan_config_derive::{Config, ConfigEnum};
|
||||
|
||||
#[derive(Clone, Copy, ConfigEnum)]
|
||||
#[repr(u8)]
|
||||
enum Mode {
|
||||
Safe = 1,
|
||||
#[config_enum(label = "Full authority")]
|
||||
FullAuthority = 7,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct EnumConfig {
|
||||
#[config(enum, id = 1, key = "mode", unit = "mode")]
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(Mode::Safe.wire_value(), 1);
|
||||
assert!(matches!(Mode::try_from_wire(7), Some(Mode::FullAuthority)));
|
||||
assert_eq!(Mode::CONFIG_ENUM_OPTIONS[1], (7, "Full authority"));
|
||||
assert_eq!(
|
||||
EnumConfig::DESCRIPTORS[0].enum_options,
|
||||
Mode::CONFIG_ENUM_OPTIONS
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct RootBooleanConfig {
|
||||
#[config(id = 1, key = "enabled", unit = "bool", default = true)]
|
||||
#[config(id = 1, key = "enabled", unit = "bool")]
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +1,22 @@
|
||||
use kaptan_config::{
|
||||
ConfigAggregate, ConfigSection, ConfigValue, ConfigViolation, FieldId, FieldWriteError,
|
||||
ValidateFields, ValidationRule,
|
||||
Config, ConfigEnum, ConfigValue, ConfigViolation, FieldId, FieldWriteError, ValidationRule,
|
||||
};
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct LocalSection {
|
||||
#[config(
|
||||
id = 1,
|
||||
key = "local.first",
|
||||
unit = "count",
|
||||
default = 2,
|
||||
range(min = 1, max = 9)
|
||||
)]
|
||||
#[config(id = 1, key = "local.first", unit = "count", range(min = 1, max = 9))]
|
||||
first: u32,
|
||||
#[config(
|
||||
id = 2,
|
||||
key = "local.second",
|
||||
unit = "count",
|
||||
default = 4,
|
||||
range(min = 1, max = 9)
|
||||
)]
|
||||
#[config(id = 2, key = "local.second", unit = "count", range(min = 1, max = 9))]
|
||||
second: u32,
|
||||
}
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
#[config(post = Self::validate_order)]
|
||||
struct OrderedSection {
|
||||
#[config(
|
||||
id = 3,
|
||||
key = "ordered.minimum",
|
||||
unit = "count",
|
||||
default = 1,
|
||||
range(min = 0, max = 9)
|
||||
)]
|
||||
minimum: u32,
|
||||
@@ -39,7 +24,6 @@ struct OrderedSection {
|
||||
id = 4,
|
||||
key = "ordered.maximum",
|
||||
unit = "count",
|
||||
default = 2,
|
||||
range(min = 0, max = 9)
|
||||
)]
|
||||
maximum: u32,
|
||||
@@ -58,17 +42,54 @@ impl OrderedSection {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct Aggregate {
|
||||
#[config(section)]
|
||||
local: LocalSection,
|
||||
#[config(section)]
|
||||
ordered: OrderedSection,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct BoardOwnedSection {
|
||||
#[config(
|
||||
id = 10,
|
||||
key = "board.endpoint",
|
||||
unit = "id",
|
||||
range(min = 1, max = 255)
|
||||
)]
|
||||
endpoint: u32,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct BoardOwnedAggregate {
|
||||
endpoint: BoardOwnedSection,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, ConfigEnum)]
|
||||
#[repr(u8)]
|
||||
enum TestMode {
|
||||
Quiet = 1,
|
||||
Loud = 3,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct CompactSection {
|
||||
#[config(
|
||||
id = 20,
|
||||
key = "compact.endpoint",
|
||||
unit = "id",
|
||||
range(min = 1, max = 255)
|
||||
)]
|
||||
endpoint: u8,
|
||||
#[config(enum, id = 21, key = "compact.mode", unit = "mode")]
|
||||
mode: TestMode,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generated_section_owns_every_declared_scalar_path() {
|
||||
let mut section = LocalSection::default_section().unwrap();
|
||||
let mut section = LocalSection {
|
||||
first: 2,
|
||||
second: 4,
|
||||
};
|
||||
assert_eq!(LocalSection::FIELD_COUNT, 2);
|
||||
assert_eq!(
|
||||
section.field_value(FieldId::new(2)),
|
||||
@@ -94,9 +115,52 @@ fn generated_section_owns_every_declared_scalar_path() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn narrow_scalars_and_compact_enums_keep_native_types_and_generic_metadata() {
|
||||
let mut section = CompactSection {
|
||||
endpoint: 7,
|
||||
mode: TestMode::Quiet,
|
||||
};
|
||||
assert_eq!(
|
||||
section.field_value(FieldId::new(20)),
|
||||
Some(ConfigValue::U32(7))
|
||||
);
|
||||
assert_eq!(
|
||||
CompactSection::DESCRIPTORS[1].enum_options,
|
||||
TestMode::CONFIG_ENUM_OPTIONS
|
||||
);
|
||||
assert_eq!(TestMode::Quiet.wire_value(), 1);
|
||||
assert_eq!(TestMode::try_from_wire(3), Some(TestMode::Loud));
|
||||
assert_eq!(TestMode::try_from_wire(2), None);
|
||||
|
||||
section
|
||||
.set_field(FieldId::new(21), ConfigValue::U32(3))
|
||||
.unwrap();
|
||||
assert_eq!(section.mode, TestMode::Loud);
|
||||
assert!(matches!(
|
||||
section.set_field(FieldId::new(21), ConfigValue::U32(2)),
|
||||
Err(FieldWriteError::Violation(issue))
|
||||
if issue.rule() == ValidationRule::InvalidEnumValue
|
||||
));
|
||||
assert!(matches!(
|
||||
section.set_field(FieldId::new(20), ConfigValue::U32(256)),
|
||||
Err(FieldWriteError::Violation(issue))
|
||||
if issue.rule() == ValidationRule::AboveMaximum
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aggregate_routes_writes_and_defers_declared_post_validation() {
|
||||
let mut aggregate = Aggregate::default_aggregate().unwrap();
|
||||
let mut aggregate = Aggregate {
|
||||
local: LocalSection {
|
||||
first: 2,
|
||||
second: 4,
|
||||
},
|
||||
ordered: OrderedSection {
|
||||
minimum: 1,
|
||||
maximum: 2,
|
||||
},
|
||||
};
|
||||
assert_eq!(Aggregate::FIELD_COUNT, 4);
|
||||
assert_eq!(
|
||||
aggregate.field_value(FieldId::new(2)),
|
||||
@@ -106,7 +170,7 @@ fn aggregate_routes_writes_and_defers_declared_post_validation() {
|
||||
.set_field(FieldId::new(3), ConfigValue::U32(3))
|
||||
.unwrap();
|
||||
assert!(matches!(
|
||||
aggregate.validate_fields(),
|
||||
aggregate.validate(),
|
||||
Err(issue)
|
||||
if issue.primary() == Some(FieldId::new(3))
|
||||
&& issue.related_field() == Some(FieldId::new(4))
|
||||
@@ -115,5 +179,101 @@ fn aggregate_routes_writes_and_defers_declared_post_validation() {
|
||||
aggregate
|
||||
.set_field(FieldId::new(4), ConfigValue::U32(3))
|
||||
.unwrap();
|
||||
aggregate.validate_fields().unwrap();
|
||||
aggregate.validate().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aggregate_derives_its_flattened_descriptor_order() {
|
||||
let descriptors: Vec<_> = (0..Aggregate::FIELD_COUNT)
|
||||
.map(|index| Aggregate::descriptor(index).unwrap())
|
||||
.collect();
|
||||
assert_eq!(
|
||||
descriptors
|
||||
.iter()
|
||||
.map(|descriptor| descriptor.id.get())
|
||||
.collect::<Vec<_>>(),
|
||||
[1, 2, 3, 4]
|
||||
);
|
||||
assert!(Aggregate::descriptor(Aggregate::FIELD_COUNT).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn factory_values_are_owned_outside_the_generated_schema() {
|
||||
let mut aggregate = BoardOwnedAggregate {
|
||||
endpoint: BoardOwnedSection { endpoint: 42 },
|
||||
};
|
||||
assert_eq!(BoardOwnedAggregate::FIELD_COUNT, 1);
|
||||
assert_eq!(
|
||||
aggregate.field_value(FieldId::new(10)),
|
||||
Some(ConfigValue::U32(42))
|
||||
);
|
||||
aggregate
|
||||
.set_field(FieldId::new(10), ConfigValue::U32(43))
|
||||
.unwrap();
|
||||
aggregate.validate().unwrap();
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct DuplicateChildren {
|
||||
first: LocalSection,
|
||||
second: LocalSection,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct TransparentRoot {
|
||||
local: LocalSection,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct FirstKeyOwner {
|
||||
#[config(id = 30, key = "shared.key", unit = "count")]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct SecondKeyOwner {
|
||||
#[config(id = 31, key = "shared.key", unit = "count")]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct DuplicateKeysAcrossChildren {
|
||||
first: FirstKeyOwner,
|
||||
second: SecondKeyOwner,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schema_fingerprint_is_generated_and_one_child_wrappers_are_transparent() {
|
||||
assert_eq!(TransparentRoot::SCHEMA_ID, LocalSection::SCHEMA_ID);
|
||||
assert_ne!(Aggregate::SCHEMA_ID, LocalSection::SCHEMA_ID);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recursive_tree_rejects_duplicate_field_ids() {
|
||||
let duplicate = DuplicateChildren {
|
||||
first: LocalSection {
|
||||
first: 2,
|
||||
second: 4,
|
||||
},
|
||||
second: LocalSection {
|
||||
first: 2,
|
||||
second: 4,
|
||||
},
|
||||
};
|
||||
assert!(matches!(
|
||||
duplicate.validate(),
|
||||
Err(issue) if issue.rule() == ValidationRule::Inconsistent
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recursive_tree_rejects_duplicate_display_keys() {
|
||||
let duplicate = DuplicateKeysAcrossChildren {
|
||||
first: FirstKeyOwner { value: 1 },
|
||||
second: SecondKeyOwner { value: 2 },
|
||||
};
|
||||
assert!(matches!(
|
||||
duplicate.validate(),
|
||||
Err(issue) if issue.rule() == ValidationRule::Inconsistent
|
||||
));
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
use kaptan_config_derive::ConfigEnum;
|
||||
|
||||
#[derive(ConfigEnum)]
|
||||
#[repr(u8)]
|
||||
enum ImplicitDiscriminant {
|
||||
First = 1,
|
||||
Second,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: ConfigEnum variants require explicit u8 discriminants
|
||||
--> tests/ui/config_enum_implicit_discriminant.rs:7:5
|
||||
|
|
||||
7 | Second,
|
||||
| ^^^^^^
|
||||
@@ -0,0 +1,10 @@
|
||||
use kaptan_config_derive::ConfigEnum;
|
||||
|
||||
#[derive(ConfigEnum)]
|
||||
#[repr(u8)]
|
||||
enum LabelWithNul {
|
||||
#[config_enum(label = "invalid\0label")]
|
||||
Value = 1,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: ConfigEnum display labels must be non-empty text without NUL bytes
|
||||
--> tests/ui/config_enum_label_nul.rs:6:27
|
||||
|
|
||||
6 | #[config_enum(label = "invalid\0label")]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1,10 @@
|
||||
use kaptan_config_derive::ConfigEnum;
|
||||
|
||||
#[derive(ConfigEnum)]
|
||||
#[repr(u8)]
|
||||
enum LabelTooManyBytes {
|
||||
#[config_enum(label = "şşşşşşşşşşşşşşşşş")]
|
||||
Value = 1,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: ConfigEnum display label exceeds the 32-byte wire limit
|
||||
--> tests/ui/config_enum_label_too_many_bytes.rs:6:27
|
||||
|
|
||||
6 | #[config_enum(label = "şşşşşşşşşşşşşşşşş")]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1,8 @@
|
||||
use kaptan_config_derive::ConfigEnum;
|
||||
|
||||
#[derive(ConfigEnum)]
|
||||
enum MissingRepresentation {
|
||||
First = 1,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: ConfigEnum requires exactly #[repr(u8)]
|
||||
--> tests/ui/config_enum_missing_repr.rs:4:6
|
||||
|
|
||||
4 | enum MissingRepresentation {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1,9 @@
|
||||
use kaptan_config_derive::ConfigEnum;
|
||||
|
||||
#[derive(ConfigEnum)]
|
||||
#[repr(u8)]
|
||||
enum Payload {
|
||||
Value(u8) = 1,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: ConfigEnum variants cannot contain fields
|
||||
--> tests/ui/config_enum_payload.rs:6:10
|
||||
|
|
||||
6 | Value(u8) = 1,
|
||||
| ^^^^
|
||||
@@ -1,9 +0,0 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
struct DefaultBelowMinimum {
|
||||
#[config(id = 1, key = "value", unit = "count", default = 1, range(min = 2, max = 3))]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,5 +0,0 @@
|
||||
error: configuration default is below its declared minimum
|
||||
--> tests/ui/default_below_minimum.rs:5:63
|
||||
|
|
||||
5 | #[config(id = 1, key = "value", unit = "count", default = 1, range(min = 2, max = 3))]
|
||||
| ^
|
||||
@@ -1,9 +0,0 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
struct NonFiniteDefault {
|
||||
#[config(id = 1, key = "value", unit = "ratio", default = 1e100, finite)]
|
||||
value: f32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,5 +0,0 @@
|
||||
error: configuration default violates finite
|
||||
--> tests/ui/default_violates_finite.rs:5:63
|
||||
|
|
||||
5 | #[config(id = 1, key = "value", unit = "ratio", default = 1e100, finite)]
|
||||
| ^^^^^
|
||||
@@ -1,9 +0,0 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
struct ZeroDefault {
|
||||
#[config(id = 1, key = "value", unit = "count", default = 0, nonzero)]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,5 +0,0 @@
|
||||
error: configuration default violates nonzero
|
||||
--> tests/ui/default_violates_nonzero.rs:5:63
|
||||
|
|
||||
5 | #[config(id = 1, key = "value", unit = "count", default = 0, nonzero)]
|
||||
| ^
|
||||
@@ -0,0 +1,13 @@
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(Config)]
|
||||
struct DisplayKeyTooLong {
|
||||
#[config(
|
||||
id = 1,
|
||||
key = "configuration.display.key.with.more.than.forty.eight.bytes",
|
||||
unit = "count"
|
||||
)]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: configuration display key exceeds the 48-byte wire limit
|
||||
--> tests/ui/display_key_too_long.rs:7:15
|
||||
|
|
||||
7 | key = "configuration.display.key.with.more.than.forty.eight.bytes",
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1,11 @@
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(Config)]
|
||||
struct DuplicateDisplayKey {
|
||||
#[config(id = 1, key = "duplicate.key", unit = "count")]
|
||||
first: u32,
|
||||
#[config(id = 2, key = "duplicate.key", unit = "count")]
|
||||
second: u32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: duplicate configuration display key
|
||||
--> tests/ui/duplicate_display_key.rs:7:28
|
||||
|
|
||||
7 | #[config(id = 2, key = "duplicate.key", unit = "count")]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
@@ -1,6 +1,6 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct DuplicateId {
|
||||
#[config(id = 7, nonzero)]
|
||||
first: u32,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct DuplicateRange {
|
||||
#[config(id = 7, range(min = 1), range(min = 2))]
|
||||
value: u32,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct Empty {}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,4 +1,4 @@
|
||||
error: ConfigValidate requires at least one configured field or section
|
||||
error: Config requires at least one field
|
||||
--> tests/ui/empty.rs:4:8
|
||||
|
|
||||
4 | struct Empty {}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(Config)]
|
||||
struct PrimitiveEnumMarker {
|
||||
#[config(enum, id = 1, key = "mode", unit = "mode")]
|
||||
mode: u8,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: config(enum) requires a ConfigEnum-derived enum type
|
||||
--> tests/ui/enum_marker_on_primitive.rs:6:11
|
||||
|
|
||||
6 | mode: u8,
|
||||
| ^^
|
||||
@@ -0,0 +1,15 @@
|
||||
use kaptan_config_derive::{Config, ConfigEnum};
|
||||
|
||||
#[derive(Clone, Copy, ConfigEnum)]
|
||||
#[repr(u8)]
|
||||
enum Mode {
|
||||
Safe = 1,
|
||||
}
|
||||
|
||||
#[derive(Config)]
|
||||
struct MissingEnumMarker {
|
||||
#[config(id = 1, key = "mode", unit = "mode")]
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: non-primitive configuration fields require config(enum)
|
||||
--> tests/ui/missing_enum_marker.rs:12:11
|
||||
|
|
||||
12 | mode: Mode,
|
||||
| ^^^^
|
||||
@@ -1,6 +1,6 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct MissingId {
|
||||
#[config(nonzero)]
|
||||
value: u32,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
error: validated configuration fields require config(id = N)
|
||||
error: scalar configuration fields require config(id = N)
|
||||
--> tests/ui/missing_id.rs:6:5
|
||||
|
|
||||
6 | value: u32,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct MissingMetadata {
|
||||
#[config(id = 7, unit = "count", default = 1, range(min = 0, max = 10))]
|
||||
#[config(id = 7, unit = "count", range(min = 0, max = 10))]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct MixedSectionAndScalar {
|
||||
#[config(section)]
|
||||
child: u32,
|
||||
#[config(id = 1, key = "scalar", unit = "count", default = 1, range(min = 0, max = 2))]
|
||||
#[config(id = 1, key = "scalar", unit = "count", range(min = 0, max = 2))]
|
||||
scalar: u32,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error: ConfigValidate records must contain either scalar config fields or config(section) fields exclusively
|
||||
--> tests/ui/mixed_section_scalar.rs:6:5
|
||||
error: Config records must contain either scalar fields or child configuration records exclusively
|
||||
--> tests/ui/mixed_section_scalar.rs:5:5
|
||||
|
|
||||
6 | child: u32,
|
||||
5 | child: u32,
|
||||
| ^^^^^
|
||||
@@ -1,8 +1,8 @@
|
||||
use kaptan_config_derive::ConfigValidate;
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(ConfigValidate)]
|
||||
#[derive(Config)]
|
||||
struct InvalidRange {
|
||||
#[config(id = 1, key = "value", unit = "count", default = 2, range(min = 3, max = 1))]
|
||||
#[config(id = 1, key = "value", unit = "count", range(min = 3, max = 1))]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(Config)]
|
||||
struct UnitTooLong {
|
||||
#[config(id = 1, key = "value", unit = "seventeen_bytes___")]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: configuration unit exceeds the 16-byte wire limit
|
||||
--> tests/ui/unit_too_long.rs:5:44
|
||||
|
|
||||
5 | #[config(id = 1, key = "value", unit = "seventeen_bytes___")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1,9 @@
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(Config)]
|
||||
struct UnsupportedDefault {
|
||||
#[config(id = 1, key = "value", unit = "count", default = 1)]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: supported field config rules are id, key, unit, enum, finite, nonzero, and range
|
||||
--> tests/ui/unsupported_default.rs:5:53
|
||||
|
|
||||
5 | #[config(id = 1, key = "value", unit = "count", default = 1)]
|
||||
| ^^^^^^^
|
||||
@@ -0,0 +1,10 @@
|
||||
use kaptan_config_derive::Config;
|
||||
|
||||
#[derive(Config)]
|
||||
#[config(external_defaults)]
|
||||
struct UnsupportedExternalDefaults {
|
||||
#[config(id = 1, key = "value", unit = "count")]
|
||||
value: u32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: struct config options are crate = path and post = path
|
||||
--> tests/ui/unsupported_external_defaults.rs:4:10
|
||||
|
|
||||
4 | #[config(external_defaults)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
Reference in new issue
Block a user