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#[cfg(feature = "alloc")]
86extern crate alloc;
87
88pub mod codec;
89pub mod collation;
90pub mod crypto;
91pub mod error;
92pub mod login7;
93pub mod packet;
94pub mod prelogin;
95pub mod rpc;
96pub mod sql_batch;
97pub mod token;
98pub mod tvp;
99pub mod types;
100pub mod version;
101
102pub use error::ProtocolError;
103pub use login7::{
104 FeatureExtension, FeatureId, Login7, OptionFlags1, OptionFlags2, OptionFlags3, TypeFlags,
105};
106pub use packet::{
107 DEFAULT_PACKET_SIZE, MAX_PACKET_SIZE, PACKET_HEADER_SIZE, PacketHeader, PacketStatus,
108 PacketType,
109};
110pub use prelogin::{EncryptionLevel, PreLogin, PreLoginOption};
111pub use rpc::{ParamFlags, ProcId, RpcOptionFlags, RpcParam, RpcRequest, TypeInfo as RpcTypeInfo};
112pub use sql_batch::{SqlBatch, encode_sql_batch, encode_sql_batch_with_transaction};
113pub use token::{
114 ColMetaData, Collation, ColumnData, Done, DoneInProc, DoneProc, DoneStatus, EnvChange,
115 EnvChangeType, EnvChangeValue, FeatureExtAck, FedAuthInfo, LoginAck, NbcRow, Order, RawRow,
116 ReturnValue, ServerError, ServerInfo, SessionState, SspiToken, Token, TokenParser, TokenType,
117 TypeInfo,
118};
119pub use tvp::{
120 TVP_END_TOKEN, TVP_ROW_TOKEN, TVP_TYPE_ID, TvpColumnDef as TvpWireColumnDef, TvpColumnFlags,
121 TvpEncoder, TvpWireType, encode_tvp_bit, encode_tvp_date, encode_tvp_datetime2,
122 encode_tvp_datetimeoffset, encode_tvp_decimal, encode_tvp_float, encode_tvp_guid,
123 encode_tvp_int, encode_tvp_null, encode_tvp_nvarchar, encode_tvp_time, encode_tvp_varbinary,
124};
125pub use types::{ColumnFlags, TypeId, Updateable};
126pub use version::TdsVersion;
127
128// Always Encrypted metadata types
129pub use crypto::{
130 ALGORITHM_AEAD_AES_256_CBC_HMAC_SHA256, COLUMN_FLAG_ENCRYPTED, CekTable, CekTableEntry,
131 CekValue, ColumnCryptoInfo, CryptoMetadata, ENCRYPTION_TYPE_DETERMINISTIC,
132 ENCRYPTION_TYPE_RANDOMIZED, EncryptionTypeWire, NORMALIZATION_RULE_VERSION,
133 is_column_encrypted,
134};