Skip to content

Commit 1d3bbc6

Browse files
committed
update
1 parent 382d284 commit 1d3bbc6

10 files changed

Lines changed: 946 additions & 1 deletion

Cargo.lock

Lines changed: 63 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kconfig-serde/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ categories = ["encoding", "config", "development-tools"]
1111

1212
[dependencies]
1313
serde = { version = "1.0", features = ["derive"] }
14+
schemars = "1.0.4"
15+
serde_json = "1.0"
1416
anyhow = "1.0"
1517
thiserror = "2"
1618

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
//! Comprehensive example demonstrating JSON Schema to Kconfig conversion
2+
//!
3+
//! This example shows how to use the new two-step serialization process
4+
//! to generate complex Kconfig files with nested structures, help text,
5+
//! and type safety.
6+
7+
use kconfig_serde::{from_json_schema_with_help, SimpleSchemaHelpProvider};
8+
use schemars::JsonSchema;
9+
use serde::{Serialize, Deserialize};
10+
11+
#[derive(Serialize, Deserialize, JsonSchema)]
12+
struct AppConfig {
13+
/// Application basic settings
14+
general: GeneralConfig,
15+
/// Database connection settings
16+
database: DatabaseConfig,
17+
/// Web server configuration
18+
server: ServerConfig,
19+
}
20+
21+
#[derive(Serialize, Deserialize, JsonSchema)]
22+
struct GeneralConfig {
23+
/// Enable debug logging and features
24+
debug_mode: bool,
25+
/// Application version string
26+
version: String,
27+
/// Maximum number of worker threads
28+
max_workers: u32,
29+
}
30+
31+
#[derive(Serialize, Deserialize, JsonSchema)]
32+
struct DatabaseConfig {
33+
/// Database connection settings
34+
connection: ConnectionConfig,
35+
/// Connection pool settings
36+
pool: PoolConfig,
37+
}
38+
39+
#[derive(Serialize, Deserialize, JsonSchema)]
40+
struct ConnectionConfig {
41+
/// Database server hostname
42+
host: String,
43+
/// Database server port
44+
port: u16,
45+
/// Database name
46+
database: String,
47+
/// Enable SSL/TLS encryption
48+
ssl_enabled: bool,
49+
}
50+
51+
#[derive(Serialize, Deserialize, JsonSchema)]
52+
struct PoolConfig {
53+
/// Maximum number of connections in pool
54+
max_connections: u32,
55+
/// Connection timeout in seconds
56+
timeout_seconds: u64,
57+
/// Enable connection health checks
58+
health_checks: bool,
59+
}
60+
61+
#[derive(Serialize, Deserialize, JsonSchema)]
62+
struct ServerConfig {
63+
/// Server bind address
64+
bind_address: String,
65+
/// Server listen port
66+
port: u16,
67+
/// Enable HTTPS
68+
https_enabled: bool,
69+
/// SSL/TLS certificate path
70+
cert_path: Option<String>,
71+
}
72+
73+
fn main() -> Result<(), Box<dyn std::error::Error>> {
74+
// Create a comprehensive help provider with detailed documentation
75+
let mut help_provider = SimpleSchemaHelpProvider::new();
76+
77+
// General configuration help
78+
help_provider.add_help_text("general.debug_mode", "Enable debug mode for development and troubleshooting");
79+
help_provider.add_help_text("general.version", "Application version string for identification");
80+
help_provider.add_help_text("general.max_workers", "Maximum number of concurrent worker threads");
81+
82+
// Database connection help
83+
help_provider.add_help_text("database.connection.host", "Database server hostname or IP address");
84+
help_provider.add_help_text("database.connection.port", "Database server port number (typically 5432 for PostgreSQL, 3306 for MySQL)");
85+
help_provider.add_help_text("database.connection.database", "Name of the database to connect to");
86+
help_provider.add_help_text("database.connection.ssl_enabled", "Enable SSL/TLS encryption for database connections");
87+
88+
// Database pool help
89+
help_provider.add_help_text("database.pool.max_connections", "Maximum number of database connections in the pool");
90+
help_provider.add_help_text("database.pool.timeout_seconds", "Timeout in seconds for database connection attempts");
91+
help_provider.add_help_text("database.pool.health_checks", "Enable periodic connection health checks");
92+
93+
// Server configuration help
94+
help_provider.add_help_text("server.bind_address", "IP address to bind the server to (0.0.0.0 for all interfaces)");
95+
help_provider.add_help_text("server.port", "Port number for the server to listen on");
96+
help_provider.add_help_text("server.https_enabled", "Enable HTTPS/TLS for secure connections");
97+
help_provider.add_help_text("server.cert_path", "Path to SSL/TLS certificate file (required when HTTPS is enabled)");
98+
99+
// Create example configuration
100+
let config = AppConfig {
101+
general: GeneralConfig {
102+
debug_mode: false,
103+
version: "1.0.0".to_string(),
104+
max_workers: 8,
105+
},
106+
database: DatabaseConfig {
107+
connection: ConnectionConfig {
108+
host: "localhost".to_string(),
109+
port: 5432,
110+
database: "myapp".to_string(),
111+
ssl_enabled: true,
112+
},
113+
pool: PoolConfig {
114+
max_connections: 20,
115+
timeout_seconds: 30,
116+
health_checks: true,
117+
},
118+
},
119+
server: ServerConfig {
120+
bind_address: "0.0.0.0".to_string(),
121+
port: 8080,
122+
https_enabled: true,
123+
cert_path: Some("/etc/ssl/certs/server.crt".to_string()),
124+
},
125+
};
126+
127+
// Convert to Kconfig using the new two-step approach
128+
let kconfig = from_json_schema_with_help(&config, help_provider)?;
129+
130+
println!("# Generated Kconfig from JSON Schema\n");
131+
println!("{}", kconfig.to_string());
132+
133+
println!("\n# Key Features Demonstrated:");
134+
println!("- ✅ Nested structure support with automatic menu generation");
135+
println!("- ✅ Type-safe conversion using schemars");
136+
println!("- ✅ Comprehensive help text integration");
137+
println!("- ✅ Support for optional fields (cert_path)");
138+
println!("- ✅ Proper boolean, string, and integer handling");
139+
println!("- ✅ Human-readable field name formatting");
140+
141+
Ok(())
142+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use kconfig_serde::from_json_schema;
2+
use schemars::{schema_for, JsonSchema};
3+
use serde_json;
4+
use serde::Serialize;
5+
6+
#[derive(Serialize, JsonSchema)]
7+
struct DatabaseConfig {
8+
connection: ConnectionConfig,
9+
pool: PoolConfig,
10+
}
11+
12+
#[derive(Serialize, JsonSchema)]
13+
struct ConnectionConfig {
14+
host: String,
15+
port: u16,
16+
ssl_enabled: bool,
17+
}
18+
19+
#[derive(Serialize, JsonSchema)]
20+
struct PoolConfig {
21+
max_connections: u32,
22+
timeout_seconds: u64,
23+
}
24+
25+
fn main() -> Result<(), Box<dyn std::error::Error>> {
26+
let schema = schema_for!(DatabaseConfig);
27+
println!("Generated JSON Schema:");
28+
println!("{}", serde_json::to_string_pretty(&schema)?);
29+
30+
let config = DatabaseConfig {
31+
connection: ConnectionConfig {
32+
host: "localhost".to_string(),
33+
port: 5432,
34+
ssl_enabled: true,
35+
},
36+
pool: PoolConfig {
37+
max_connections: 20,
38+
timeout_seconds: 30,
39+
},
40+
};
41+
42+
match from_json_schema(&config) {
43+
Ok(result) => {
44+
println!("\nGenerated Kconfig:");
45+
println!("{}", result.to_string());
46+
}
47+
Err(e) => {
48+
println!("\nError: {}", e);
49+
}
50+
}
51+
52+
Ok(())
53+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use kconfig_serde::from_json_schema;
2+
use schemars::JsonSchema;
3+
4+
#[derive(JsonSchema)]
5+
struct NestedConfig {
6+
general: GeneralConfig,
7+
network: NetworkConfig,
8+
}
9+
10+
#[derive(JsonSchema)]
11+
struct GeneralConfig {
12+
debug_mode: bool,
13+
log_level: String,
14+
}
15+
16+
#[derive(JsonSchema)]
17+
struct NetworkConfig {
18+
enabled: bool,
19+
hostname: String,
20+
}
21+
22+
fn main() -> Result<(), Box<dyn std::error::Error>> {
23+
let config = NestedConfig {
24+
general: GeneralConfig {
25+
debug_mode: true,
26+
log_level: "info".to_string(),
27+
},
28+
network: NetworkConfig {
29+
enabled: true,
30+
hostname: "localhost".to_string(),
31+
},
32+
};
33+
34+
let result = from_json_schema(&config)?;
35+
let output = result.to_string();
36+
37+
println!("Generated Kconfig:");
38+
println!("{}", output);
39+
println!("=== DEBUG INFO ===");
40+
println!("Contains 'menu \"GeneralConfig\"': {}", output.contains("menu \"GeneralConfig\""));
41+
println!("Contains 'menu \"NetworkConfig\"': {}", output.contains("menu \"NetworkConfig\""));
42+
println!("Contains 'config DEBUG_MODE': {}", output.contains("config DEBUG_MODE"));
43+
println!("Contains 'config LOG_LEVEL': {}", output.contains("config LOG_LEVEL"));
44+
println!("Contains 'config ENABLED': {}", output.contains("config ENABLED"));
45+
println!("Contains 'config HOSTNAME': {}", output.contains("config HOSTNAME"));
46+
47+
Ok(())
48+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use kconfig_serde::from_json_schema;
2+
use schemars::{schema_for, JsonSchema};
3+
use serde_json;
4+
use serde::Serialize;
5+
6+
#[derive(Serialize, JsonSchema)]
7+
struct ServerConfig {
8+
bind_address: String,
9+
port: u16,
10+
https_enabled: bool,
11+
cert_path: Option<String>,
12+
}
13+
14+
fn main() -> Result<(), Box<dyn std::error::Error>> {
15+
let schema = schema_for!(ServerConfig);
16+
println!("Generated JSON Schema:");
17+
println!("{}", serde_json::to_string_pretty(&schema)?);
18+
19+
let config = ServerConfig {
20+
bind_address: "0.0.0.0".to_string(),
21+
port: 8080,
22+
https_enabled: true,
23+
cert_path: Some("/etc/ssl/certs/server.crt".to_string()),
24+
};
25+
26+
match from_json_schema(&config) {
27+
Ok(result) => {
28+
println!("\nGenerated Kconfig:");
29+
println!("{}", result.to_string());
30+
}
31+
Err(e) => {
32+
println!("\nError: {}", e);
33+
}
34+
}
35+
36+
Ok(())
37+
}

0 commit comments

Comments
 (0)