|
4 | 4 | [](http://www.apache.org/licenses/LICENSE-2.0) |
5 | 5 | [](https://crates.io/crates/kode-bridge) |
6 | 6 |
|
7 | | -**[中文](./README_CN.md) | English** |
| 7 | +<!-- **[中文](./README_CN.md) | English** --> |
8 | 8 |
|
9 | 9 | **kode-bridge** is a modern Rust library that implements **HTTP Over IPC** for cross-platform (macOS, Linux, Windows) communication. It provides both **client and server** capabilities with elegant HTTP-style request/response and real-time streaming through Unix Domain Sockets or Windows Named Pipes, featuring a fluent API similar to reqwest with comprehensive connection pooling, advanced error handling, and high-performance streaming. |
10 | 10 |
|
@@ -53,88 +53,70 @@ serde_json = "1.0" |
53 | 53 | ### Basic Usage |
54 | 54 |
|
55 | 55 | ```rust |
56 | | -use kode_bridge::{IpcHttpClient, IpcStreamClient}; |
57 | | -use serde_json::json; |
| 56 | +use dotenvy::dotenv; |
| 57 | +use kode_bridge::{IpcHttpClient, Result}; |
| 58 | +use std::env; |
58 | 59 | use std::time::Duration; |
59 | 60 |
|
60 | 61 | #[tokio::main] |
61 | | -async fn main() -> Result<(), Box<dyn std::error::Error>> { |
62 | | - // Automatically detect platform and use appropriate IPC path |
| 62 | +async fn main() -> Result<()> { |
| 63 | + dotenv().ok(); |
| 64 | + |
| 65 | + // Use platform-appropriate environment variable with fallback |
63 | 66 | #[cfg(unix)] |
64 | | - let ipc_path = "/tmp/my_service.sock"; |
| 67 | + let ipc_path = env::var("CUSTOM_SOCK").unwrap_or_else(|_| "/tmp/example.sock".to_string()); |
65 | 68 | #[cfg(windows)] |
66 | | - let ipc_path = r"\\.\pipe\my_service"; |
67 | | - |
68 | | - // HTTP-style client for request/response |
69 | | - let client = IpcHttpClient::new(ipc_path)?; |
70 | | - |
71 | | - // 🔥 New fluent API - like reqwest! |
72 | | - let response = client |
73 | | - .get("/api/version") |
74 | | - .timeout(Duration::from_secs(5)) |
75 | | - .send() |
76 | | - .await?; |
77 | | - |
78 | | - println!("Status: {}", response.status()); |
79 | | - println!("Success: {}", response.is_success()); |
80 | | - |
81 | | - // Type-safe JSON parsing |
82 | | - #[derive(serde::Deserialize)] |
83 | | - struct ApiResponse { |
84 | | - version: String, |
85 | | - meta: bool, |
86 | | - } |
87 | | - |
88 | | - let data: ApiResponse = response.json()?; |
89 | | - println!("Version: {}", data.version); |
90 | | - |
91 | | - // POST with JSON body |
92 | | - let update_data = json!({"user": "alice", "action": "login"}); |
| 69 | + let ipc_path = env::var("CUSTOM_PIPE").unwrap_or_else(|_| r"\\.\pipe\example".to_string()); |
| 70 | + |
| 71 | + println!("📡 Connecting to: {}", ipc_path); |
| 72 | + |
| 73 | + // Create client with modern API |
| 74 | + let client = IpcHttpClient::new(&ipc_path)?; |
| 75 | + |
| 76 | + // Use the new fluent API with custom headers and timeout |
93 | 77 | let response = client |
94 | | - .post("/api/auth") |
95 | | - .json_body(&update_data) |
| 78 | + .get("/version") |
| 79 | + .header("Authorization", "Bearer token123") |
| 80 | + .header("X-Custom-Header", "custom-value") |
96 | 81 | .timeout(Duration::from_secs(10)) |
97 | 82 | .send() |
98 | 83 | .await?; |
99 | | - |
100 | | - if response.is_success() { |
101 | | - println!("Auth successful!"); |
| 84 | + |
| 85 | + println!("🔍 Response Details:"); |
| 86 | + println!(" Status: {}", response.status()); |
| 87 | + println!(" Success: {}", response.is_success()); |
| 88 | + println!(" Content Length: {}", response.content_length()); |
| 89 | + |
| 90 | + // Parse and display JSON response |
| 91 | + match response.json_value() { |
| 92 | + Ok(json) => println!("📄 JSON Response: {:#}", json), |
| 93 | + Err(e) => { |
| 94 | + println!("📄 Raw Response: {:?}", response.body()?); |
| 95 | + println!("⚠️ JSON parse error: {}", e); |
| 96 | + } |
102 | 97 | } |
103 | | - |
104 | | - // Real-time streaming client |
105 | | - let stream_client = IpcStreamClient::new(ipc_path)?; |
106 | | - |
107 | | - // Monitor traffic data in real-time |
108 | | - #[derive(serde::Deserialize, Debug)] |
109 | | - struct TrafficData { |
110 | | - up: u64, |
111 | | - down: u64, |
| 98 | + |
| 99 | + // Show pool stats if available |
| 100 | + if let Some(stats) = client.pool_stats() { |
| 101 | + println!("📊 Pool Stats: {}", stats); |
112 | 102 | } |
113 | | - |
114 | | - let traffic_data: Vec<TrafficData> = stream_client |
115 | | - .get("/traffic") |
116 | | - .timeout(Duration::from_secs(5)) |
117 | | - .json_results() |
118 | | - .await?; |
119 | | - |
120 | | - println!("Collected {} traffic samples", traffic_data.len()); |
121 | | - |
| 103 | + |
122 | 104 | Ok(()) |
123 | 105 | } |
124 | 106 | ``` |
125 | 107 |
|
126 | 108 | ### Server Usage |
127 | 109 |
|
128 | 110 | ```rust |
129 | | -use kode_bridge::{IpcHttpServer, Router, HttpResponse, Result}; |
| 111 | +use kode_bridge::{ipc_http_server::{HttpResponse, IpcHttpServer, Router}, Result}; |
130 | 112 | use serde_json::json; |
131 | 113 |
|
132 | 114 | #[tokio::main] |
133 | 115 | async fn main() -> Result<()> { |
134 | 116 | // Create HTTP server with routing |
135 | 117 | let router = Router::new() |
136 | | - .get("/health", |_| async move { |
137 | | - HttpResponse::json(&json!({"status": "healthy"})) |
| 118 | + .get("/version", |_| async move { |
| 119 | + HttpResponse::json(&json!({"version": "1.0.0"})) |
138 | 120 | }) |
139 | 121 | .post("/api/data", |ctx| async move { |
140 | 122 | let data: serde_json::Value = ctx.json()?; |
|
0 commit comments