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
//! # ethereum-mysql
//!
//! Type-safe, ergonomic wrappers for Ethereum types — the missing bridge between
//! **Rust application code** and **SQL databases** for Web3 developers.
//!
//! ## Why this crate?
//!
//! While [alloy](https://crates.io/crates/alloy) provides the foundational Ethereum types,
//! writing production Web3 backend code still requires tedious boilerplate:
//!
//! ```text
//! // Without ethereum-mysql: manual conversions everywhere
//! let balance: U256 = row.get::<String, _>("balance").parse()?;
//! let new_balance = balance + U256::from(100u64); // verbose, no primitive ops
//! let fee = balance * U256::from(25) / U256::from(10000); // unreadable
//! ```
//!
//! **With ethereum-mysql, it's just:**
//!
//! ```text
//! let balance: SqlU256 = row.get("balance");
//! let new_balance = balance + 100u64; // natural arithmetic
//! let fee = balance * 25u64 / 10000u64; // clean & readable
//! ```
//!
//! This crate provides SQL-compatible wrappers for common Ethereum types (`Address`, `U256`, `U128`, `FixedBytes`, `Bytes`),
//! designed for use with the async SQLx toolkit and relational databases (MySQL, PostgreSQL, SQLite).
//!
//! ## Supported Types
//!
//! - **SqlAddress**: Type-safe wrapper for `alloy::primitives::Address` (Ethereum address)
//! - **SqlU128**: Wrapper for `alloy::primitives::U128` (128-bit unsigned integer, common for Solidity `uint128`)
//! - **SqlU256**: Wrapper for `alloy::primitives::U256` (256-bit unsigned integer) with full arithmetic and conversion support
//! - **`SqlFixedBytes<N>`**: Generic wrapper for fixed-size byte arrays (e.g. hashes, topics)
//! - **SqlHash**/**SqlTopicHash**: Type aliases for `SqlFixedBytes<32>` (commonly used for hashes/topics)
//! - **SqlBytes**: Wrapper for dynamic-length byte arrays
//!
//! ## Design Highlights
//!
//! - **🔥 Intuitive Arithmetic**: Direct `+`, `-`, `*`, `/`, `%` between `SqlU256`/`SqlU128` and Rust primitives — write `balance * 25u64 / 10000u64` instead of `balance * U256::from(25) / U256::from(10000)`.
//! - **🚀 API-Ready**: Use `SqlAddress`/`SqlU256`/`SqlU128` directly in your `#[derive(Serialize, Deserialize, FromRow)]` request/response structs. Zero manual conversion in web handlers.
//! - **Binary storage**: All types are stored as raw big-endian bytes (BINARY/BYTEA/BLOB) for optimal storage efficiency and performance.
//! Follows the same approach as [alloy-rs/core PR #970](https://github.com/alloy-rs/core/pull/970) and [PR #1020](https://github.com/alloy-rs/core/pull/1020).
//! - **Type safety**: Compile-time and runtime validation for all Ethereum types.
//! - **Unified error handling**: All conversion errors use the `SqlTypeError` enum — no more `&'static str` error messages.
//!
//! ## SQLx Integration
//!
//! This crate implements the necessary SQLx traits (`Type`, `Encode`, `Decode`) for all wrappers, enabling direct use in queries and result sets without manual conversion.
//!
//! - **Multi-database support**: MySQL, PostgreSQL, SQLite (via SQLx)
//! - **Serde support**: Optional JSON serialization for all wrappers (enable the `serde` feature)
//! - **Constants**: Pre-defined constants like `SqlAddress::ZERO`, `SqlU256::ZERO`, `SqlU256::ETHER`
//! - **Compile-time macros**: Create addresses at compile time with `sqladdress!`
//!
//! ## Recommended Database Column Types
//!
//! | Type | MySQL | PostgreSQL | SQLite |
//! |--------------------|-------------|-----------|--------|
//! | SqlAddress | BINARY(20) | BYTEA | BLOB |
//! | SqlU128 | BINARY(16) | BYTEA | BLOB |
//! | SqlU256 | BINARY(32) | BYTEA | BLOB |
//! | `SqlFixedBytes<N>` | BINARY(N) | BYTEA | BLOB |
//! | SqlBytes | VARBINARY | BYTEA | BLOB |
//!
//! ## Example Usage
//!
//! ```rust
//! use ethereum_mysql::{SqlAddress, SqlU256, SqlU128, SqlHash, sqladdress};
//! use std::str::FromStr;
//!
//! // Address usage
//! let zero = SqlAddress::ZERO;
//! let addr = sqladdress!("0x742d35Cc6635C0532925a3b8D42cC72b5c2A9A1d");
//!
//! // U256 arithmetic — clean, intuitive, no manual conversions
//! let balance = SqlU256::from_str("1000000000000000000").unwrap(); // 1 ETH in wei
//! let doubled = balance * 2u64;
//! let fee = balance * 25u64 / 10000u64; // 0.25% fee, pure readability
//!
//! // U128 usage
//! let amount: SqlU128 = SqlU128::from(1000u64);
//! let half = amount / 2u64;
//!
//! // Hash usage
//! let tx_hash = SqlHash::from_str("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").unwrap();
//! ```
//!
//! ## Migration from v3.x (String Storage)
//!
//! Starting from v4.0, all types are stored as **binary** (BINARY/BYTEA/BLOB) instead of hex strings (VARCHAR/TEXT).
//! See the [CHANGELOG](https://github.com/Rollp0x/ethereum-mysql/blob/main/CHANGELOG.md) for migration guidance.
pub use SqlTypeError;
pub use ;
pub use ;
pub use ;
pub use ;
// Re-export alloy for macro usage
pub use alloy;