1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
//! # Logos Storage Rust Bindings
//!
//! This crate provides safe Rust bindings to the Logos Storage C FFI API.
//!
//! ## Safety
//!
//! This crate provides a safe wrapper around the underlying C FFI API. The following
//! safety guarantees are provided:
//!
//! - All opaque pointers are properly wrapped and never dereferenced
//! - All callback data is copied immediately
//! - Proper RAII is used for resource management
//! - Thread safety is enforced via Send/Sync traits
//!
//! ## Threading Model
//!
//! The Logos Storage system uses a single worker thread pattern:
//!
//! - **Main thread**: Rust application code
//! - **Worker thread**: Nim async runtime + storage operations
//! - **Communication**: Callback-based with Future support
//!
//! All FFI calls return immediately with a status code. The actual work happens
//! asynchronously on the worker thread, and results are delivered via callbacks.
//!
//! ## Memory Management
//!
//! - Strings allocated by Nim are freed by Nim
//! - Rust copies strings if needed for long-term storage
//! - Never store callback pointers beyond callback lifetime
//! - All opaque pointers are treated as `*mut c_void` and never dereferenced
//!
//! ## Lifecycle
//!
//! The Storage node follows a strict lifecycle:
//!
//! 1. **Create** - Create a new node with [`StorageNode::new()`]
//! 2. **Start** - Start the node with [`StorageNode::start()`] or [`StorageNode::start_async()`]
//! 3. **Stop** - Stop the node with [`StorageNode::stop()`] or [`StorageNode::stop_async()`]
//! 4. **Close** - Close the node with [`StorageNode::close()`] or [`StorageNode::close_async()`]
//! 5. **Destroy** - Destroy the node with [`StorageNode::destroy()`] or [`StorageNode::destroy_async()`]
//!
//! The node can be started and stopped multiple times, but must be closed
//! before it can be destroyed. The `Drop` implementation will automatically
//! clean up resources if the node is dropped without explicit destruction.
//!
//! ## Error Handling
//!
//! All operations return a `Result<T, StorageError>`. Errors are categorized
//! into different variants:
//!
//! - `LibraryError` - Errors from the underlying C library
//! - `NodeError` - Errors from node operations
//! - `UploadError` - Errors from upload operations
//! - `DownloadError` - Errors from download operations
//! - `StorageError` - Errors from storage operations
//! - `P2PError` - Errors from P2P operations
//! - `ConfigError` - Errors from configuration
//! - `InvalidParameter` - Invalid parameter errors
//! - `Timeout` - Operation timeout errors
//! - `Cancelled` - Operation cancelled errors
//! - `MissingCallback` - Missing callback errors
//! - `NullPointer` - Null pointer errors
//!
//! ## Example
//!
//! ```no_run
//! use storage_bindings::{LogLevel, StorageConfig, StorageNode};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Create configuration
//! let config = StorageConfig::new()
//! .log_level(LogLevel::Info)
//! .data_dir("./storage");
//!
//! // Create node
//! let node = StorageNode::new(config).await?;
//!
//! // Start node
//! node.start().await?;
//!
//! // Get node information
//! println!("Peer ID: {}", node.peer_id().await?);
//! println!("Version: {}", node.version().await?);
//!
//! // Stop and destroy node
//! node.stop().await?;
//! node.destroy().await?;
//!
//! Ok(())
//! }
//! # Ok::<(), storage_bindings::StorageError>(())
//! ```
//!
//! ## Configuration
//!
//! Configuration can be loaded from multiple sources with the following priority:
//!
//! 1. **CLI arguments** - Highest priority
//! 2. **Configuration file** - JSON file
//! 3. **Environment variables** - Variables with `STORAGE_` prefix
//! 4. **Default values** - Lowest priority
//!
//! ### Environment Variables
//!
//! - `STORAGE_DATA_DIR` - Data directory path
//! - `STORAGE_LOG_LEVEL` - Log level (trace, debug, info, notice, warn, error, fatal)
//! - `STORAGE_LOG_FORMAT` - Log format (auto, colors, nocolors, json)
//! - `STORAGE_STORAGE_QUOTA` - Storage quota in bytes (supports suffixes: K, M, G, T)
//! - `STORAGE_MAX_PEERS` - Maximum number of peers
//! - `STORAGE_DISCOVERY_PORT` - Discovery port
//! - `STORAGE_NUM_THREADS` - Number of worker threads
//! - `STORAGE_REPO_KIND` - Repository kind (fs, sqlite, leveldb)
//! - `STORAGE_NAT` - NAT configuration
//! - `STORAGE_AGENT_STRING` - Agent string
//!
//! ## Type-Safe Wrappers
//!
//! The crate provides type-safe wrappers for common storage types:
//!
//! - [`Cid`] - Content Identifier with CIDv1 validation
//! - [`PeerId`] - Peer ID with base58 validation
//! - [`MultiAddress`] - MultiAddress with format validation
//!
//! ## Testing
//!
//! The crate includes comprehensive tests:
//!
//! - Unit tests for individual components
//! - Integration tests for full workflows
//! - Memory safety tests (run with sanitizers)
//! - Thread safety tests
//!
//! Run tests with:
//!
//! ```bash
//! # Run all tests
//! cargo test
//!
//! # Run with AddressSanitizer
//! RUSTFLAGS="-Z sanitizer=address" cargo test
//!
//! # Run with ThreadSanitizer
//! RUSTFLAGS="-Z sanitizer=thread" cargo test
//! ```
// Re-export types
pub use ;
// Debug operations and types
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;