tds_protocol/
lib.rs

1//! # tds-protocol
2//!
3//! Pure implementation of the MS-TDS (Tabular Data Stream) protocol used by
4//! Microsoft SQL Server.
5//!
6//! This crate provides `no_std` compatible packet structures, token parsing,
7//! and serialization for TDS protocol versions 7.4 through 8.0.
8//!
9//! ## Features
10//!
11//! - `std` (default): Enable standard library support
12//! - `alloc`: Enable allocation without full std (requires `alloc` crate)
13//! - `encoding` (default): Enable collation-aware string encoding/decoding
14//!   via the [`Collation::encoding()`] method. Uses the `encoding_rs` crate.
15//!
16//! ## Collation-Aware VARCHAR Decoding
17//!
18//! When the `encoding` feature is enabled (default), this crate provides
19//! comprehensive support for decoding VARCHAR data with locale-specific
20//! character encodings. This is essential for databases using non-ASCII
21//! collations (e.g., Japanese, Chinese, Korean, Cyrillic, Arabic, etc.).
22//!
23//! ### Supported Encodings
24//!
25//! | Code Page | Encoding | Languages |
26//! |-----------|----------|-----------|
27//! | 874 | Windows-874 (TIS-620) | Thai |
28//! | 932 | Shift_JIS | Japanese |
29//! | 936 | GBK/GB18030 | Simplified Chinese |
30//! | 949 | EUC-KR | Korean |
31//! | 950 | Big5 | Traditional Chinese |
32//! | 1250 | Windows-1250 | Central/Eastern European |
33//! | 1251 | Windows-1251 | Cyrillic |
34//! | 1252 | Windows-1252 | Western European (default) |
35//! | 1253 | Windows-1253 | Greek |
36//! | 1254 | Windows-1254 | Turkish |
37//! | 1255 | Windows-1255 | Hebrew |
38//! | 1256 | Windows-1256 | Arabic |
39//! | 1257 | Windows-1257 | Baltic |
40//! | 1258 | Windows-1258 | Vietnamese |
41//! | UTF-8 | UTF-8 | SQL Server 2019+ collations |
42//!
43//! ### Example
44//!
45//! ```rust,ignore
46//! use tds_protocol::Collation;
47//!
48//! // Japanese collation (LCID 0x0411 = Japanese_CI_AS)
49//! let collation = Collation { lcid: 0x0411, sort_id: 0 };
50//! if let Some(encoding) = collation.encoding() {
51//!     // encoding is Shift_JIS
52//!     let (decoded, _, _) = encoding.decode(varchar_bytes);
53//! }
54//!
55//! // Check if UTF-8 collation (SQL Server 2019+)
56//! let utf8_collation = Collation { lcid: 0x0800_0409, sort_id: 0 };
57//! assert!(utf8_collation.is_utf8()); // true, no transcoding needed
58//! ```
59//!
60//! ## Design Philosophy
61//!
62//! This crate is intentionally IO-agnostic. It contains no networking logic and
63//! makes no assumptions about the async runtime. Higher-level crates build upon
64//! this foundation to provide async I/O capabilities.
65//!
66//! ## Example
67//!
68//! ```rust,ignore
69//! use tds_protocol::{PacketHeader, PacketType, PacketStatus};
70//!
71//! let header = PacketHeader {
72//!     packet_type: PacketType::SqlBatch,
73//!     status: PacketStatus::END_OF_MESSAGE,
74//!     length: 100,
75//!     spid: 0,
76//!     packet_id: 1,
77//!     window: 0,
78//! };
79//! ```
80
81#![cfg_attr(not(feature = "std"), no_std)]
82#![warn(missing_docs)]
83#![deny(unsafe_code)]
84
85// This crate requires heap allocation (String, Vec). When std is disabled,
86// the alloc feature must be enabled to provide these types.
87#[cfg(all(not(feature = "std"), not(feature = "alloc")))]
88compile_error!(
89    "tds-protocol requires either the `std` feature (default) or the `alloc` feature. \
90     Enable at least one: `--features std` or `--features alloc`"
91);
92
93#[cfg(feature = "alloc")]
94extern crate alloc;
95
96// Internal prelude for no_std compatibility - provides String, Vec, Box, etc.
97mod prelude;
98
99pub mod codec;
100pub mod collation;
101pub mod crypto;
102pub mod error;
103pub mod login7;
104pub mod packet;
105pub mod prelogin;
106pub mod rpc;
107pub mod sql_batch;
108pub mod token;
109pub mod tvp;
110pub mod types;
111pub mod version;
112
113pub use error::ProtocolError;
114pub use login7::{
115    FeatureExtension, FeatureId, Login7, OptionFlags1, OptionFlags2, OptionFlags3, TypeFlags,
116};
117pub use packet::{
118    DEFAULT_PACKET_SIZE, MAX_PACKET_SIZE, PACKET_HEADER_SIZE, PacketHeader, PacketStatus,
119    PacketType,
120};
121pub use prelogin::{EncryptionLevel, PreLogin, PreLoginOption};
122pub use rpc::{ParamFlags, ProcId, RpcOptionFlags, RpcParam, RpcRequest, TypeInfo as RpcTypeInfo};
123pub use sql_batch::{SqlBatch, encode_sql_batch, encode_sql_batch_with_transaction};
124pub use token::{
125    ColMetaData, Collation, ColumnData, Done, DoneInProc, DoneProc, DoneStatus, EnvChange,
126    EnvChangeType, EnvChangeValue, FeatureExtAck, FedAuthInfo, LoginAck, NbcRow, Order, RawRow,
127    ReturnValue, ServerError, ServerInfo, SessionState, SspiToken, Token, TokenParser, TokenType,
128    TypeInfo,
129};
130pub use tvp::{
131    TVP_END_TOKEN, TVP_ROW_TOKEN, TVP_TYPE_ID, TvpColumnDef as TvpWireColumnDef, TvpColumnFlags,
132    TvpEncoder, TvpWireType, encode_tvp_bit, encode_tvp_date, encode_tvp_datetime2,
133    encode_tvp_datetimeoffset, encode_tvp_decimal, encode_tvp_float, encode_tvp_guid,
134    encode_tvp_int, encode_tvp_null, encode_tvp_nvarchar, encode_tvp_time, encode_tvp_varbinary,
135};
136pub use types::{ColumnFlags, TypeId, Updateable};
137pub use version::{SqlServerVersion, TdsVersion};
138
139// Always Encrypted metadata types
140pub use crypto::{
141    ALGORITHM_AEAD_AES_256_CBC_HMAC_SHA256, COLUMN_FLAG_ENCRYPTED, CekTable, CekTableEntry,
142    CekValue, ColumnCryptoInfo, CryptoMetadata, ENCRYPTION_TYPE_DETERMINISTIC,
143    ENCRYPTION_TYPE_RANDOMIZED, EncryptionTypeWire, NORMALIZATION_RULE_VERSION,
144    is_column_encrypted,
145};