pcapsql_core/schema/
field.rs1use super::DataKind;
4
5#[derive(Debug, Clone, PartialEq)]
10pub struct FieldDescriptor {
11 pub name: &'static str,
13
14 pub kind: DataKind,
16
17 pub nullable: bool,
19
20 pub description: Option<&'static str>,
22}
23
24impl FieldDescriptor {
25 pub const fn new(name: &'static str, kind: DataKind) -> Self {
27 Self {
28 name,
29 kind,
30 nullable: false,
31 description: None,
32 }
33 }
34
35 pub const fn nullable(name: &'static str, kind: DataKind) -> Self {
37 Self {
38 name,
39 kind,
40 nullable: true,
41 description: None,
42 }
43 }
44
45 pub const fn with_description(mut self, desc: &'static str) -> Self {
47 self.description = Some(desc);
48 self
49 }
50
51 pub const fn set_nullable(mut self, nullable: bool) -> Self {
53 self.nullable = nullable;
54 self
55 }
56}
57
58impl FieldDescriptor {
60 pub const fn frame_number() -> Self {
62 Self::new("frame_number", DataKind::UInt64).with_description("Unique packet identifier")
63 }
64
65 pub const fn timestamp() -> Self {
67 Self::new("timestamp", DataKind::TimestampMicros)
68 .with_description("Packet capture time (UTC)")
69 }
70
71 pub const fn src_port() -> Self {
73 Self::new("src_port", DataKind::UInt16).with_description("Source port number")
74 }
75
76 pub const fn dst_port() -> Self {
78 Self::new("dst_port", DataKind::UInt16).with_description("Destination port number")
79 }
80
81 pub const fn ipv4_field(name: &'static str) -> Self {
83 Self::new(name, DataKind::UInt32)
84 }
85
86 pub const fn ipv6_field(name: &'static str) -> Self {
88 Self::new(name, DataKind::FixedBinary(16))
89 }
90
91 pub const fn mac_field(name: &'static str) -> Self {
93 Self::new(name, DataKind::FixedBinary(6))
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_field_creation() {
103 let field = FieldDescriptor::new("test", DataKind::UInt32);
104 assert_eq!(field.name, "test");
105 assert_eq!(field.kind, DataKind::UInt32);
106 assert!(!field.nullable);
107 assert!(field.description.is_none());
108 }
109
110 #[test]
111 fn test_nullable_field() {
112 let field = FieldDescriptor::nullable("optional", DataKind::String);
113 assert!(field.nullable);
114 }
115
116 #[test]
117 fn test_builder_pattern() {
118 let field = FieldDescriptor::new("count", DataKind::UInt64)
119 .set_nullable(true)
120 .with_description("Packet count");
121
122 assert!(field.nullable);
123 assert_eq!(field.description, Some("Packet count"));
124 }
125
126 #[test]
127 fn test_common_fields() {
128 let frame = FieldDescriptor::frame_number();
129 assert_eq!(frame.name, "frame_number");
130 assert_eq!(frame.kind, DataKind::UInt64);
131
132 let mac = FieldDescriptor::mac_field("src_mac");
133 assert_eq!(mac.kind, DataKind::FixedBinary(6));
134 }
135}