1use core::{
2 cell::UnsafeCell,
3 mem::MaybeUninit,
4 ops::{Deref, DerefMut},
5};
6
7use crate::{
8 env::OdbcVersion,
9 handle::{RefSQLHDESC, RefUnsafeSQLHDESC, UnsafeSQLHDESC, SQLHDESC},
10 Ident, SQLCHAR, SQLWCHAR,
11};
12
13pub trait OdbcChar {}
14
15#[repr(transparent)]
16#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
17pub struct OdbcStr<T>([T]);
18
19pub trait Ansi {}
20pub trait Unicode {}
21
22impl OdbcChar for SQLCHAR {}
23impl OdbcChar for SQLWCHAR {}
24
25impl<T> Deref for OdbcStr<T> {
26 type Target = [T];
27
28 fn deref(&self) -> &Self::Target {
29 &self.0
30 }
31}
32impl<T> DerefMut for OdbcStr<T> {
33 fn deref_mut(&mut self) -> &mut Self::Target {
34 &mut self.0
35 }
36}
37impl AsRef<OdbcStr<SQLCHAR>> for str {
38 fn as_ref(&self) -> &OdbcStr<SQLCHAR> {
39 self.as_bytes().as_ref()
40 }
41}
42impl AsMut<OdbcStr<SQLCHAR>> for str {
43 fn as_mut(&mut self) -> &mut OdbcStr<SQLCHAR> {
44 unsafe { self.as_bytes_mut().as_mut() }
45 }
46}
47impl AsRef<OdbcStr<SQLCHAR>> for [SQLCHAR] {
48 fn as_ref(&self) -> &OdbcStr<SQLCHAR> {
49 unsafe { &*(self as *const [SQLCHAR] as *const OdbcStr<SQLCHAR>) }
50 }
51}
52impl AsMut<OdbcStr<SQLCHAR>> for [SQLCHAR] {
53 fn as_mut(&mut self) -> &mut OdbcStr<SQLCHAR> {
54 unsafe { &mut *(self as *mut [SQLCHAR] as *mut OdbcStr<SQLCHAR>) }
55 }
56}
57impl AsRef<OdbcStr<SQLWCHAR>> for [SQLWCHAR] {
58 fn as_ref(&self) -> &OdbcStr<SQLWCHAR> {
59 unsafe { &*(self as *const [SQLWCHAR] as *const OdbcStr<SQLWCHAR>) }
60 }
61}
62impl AsMut<OdbcStr<SQLWCHAR>> for [SQLWCHAR] {
63 fn as_mut(&mut self) -> &mut OdbcStr<SQLWCHAR> {
64 unsafe { &mut *(self as *mut [SQLWCHAR] as *mut OdbcStr<SQLWCHAR>) }
65 }
66}
67impl AsRef<OdbcStr<UnsafeCell<SQLCHAR>>> for UnsafeCell<str> {
68 fn as_ref(&self) -> &OdbcStr<UnsafeCell<SQLCHAR>> {
69 unsafe { core::mem::transmute(self) }
72 }
73}
74impl AsRef<OdbcStr<UnsafeCell<SQLCHAR>>> for UnsafeCell<[SQLCHAR]> {
75 fn as_ref(&self) -> &OdbcStr<UnsafeCell<SQLCHAR>> {
76 unsafe { core::mem::transmute(self) }
78 }
79}
80impl AsRef<OdbcStr<UnsafeCell<SQLWCHAR>>> for UnsafeCell<[SQLWCHAR]> {
81 fn as_ref(&self) -> &OdbcStr<UnsafeCell<SQLWCHAR>> {
82 unsafe { core::mem::transmute(self) }
84 }
85}
86impl AsMut<OdbcStr<MaybeUninit<SQLCHAR>>> for [MaybeUninit<SQLCHAR>]
87where
88 [SQLCHAR]: AsMut<OdbcStr<SQLCHAR>>,
89{
90 fn as_mut(&mut self) -> &mut OdbcStr<MaybeUninit<SQLCHAR>> {
91 unsafe { &mut *(self as *mut [MaybeUninit<SQLCHAR>] as *mut OdbcStr<MaybeUninit<SQLCHAR>>) }
92 }
93}
94impl AsMut<OdbcStr<MaybeUninit<SQLWCHAR>>> for [MaybeUninit<SQLWCHAR>]
95where
96 [SQLWCHAR]: AsMut<OdbcStr<SQLWCHAR>>,
97{
98 fn as_mut(&mut self) -> &mut OdbcStr<MaybeUninit<SQLWCHAR>> {
99 unsafe {
100 &mut *(self as *mut [MaybeUninit<SQLWCHAR>] as *mut OdbcStr<MaybeUninit<SQLWCHAR>>)
101 }
102 }
103}
104
105impl<T: Ident> Ansi for T {} impl<T: Ident> Unicode for T {} impl<T: Ident> Ansi for MaybeUninit<T> where T: Ansi {}
109impl<T: Ident> Unicode for MaybeUninit<T> where T: Unicode {}
110
111impl Ansi for OdbcStr<SQLCHAR> {}
112impl Unicode for OdbcStr<SQLWCHAR> {}
113
114impl Ansi for OdbcStr<MaybeUninit<SQLCHAR>> {}
115impl Unicode for OdbcStr<MaybeUninit<SQLWCHAR>> {}
116
117impl<CH: OdbcChar> Ansi for &OdbcStr<CH> where OdbcStr<CH>: Ansi {}
118impl<CH: OdbcChar> Unicode for &OdbcStr<CH> where OdbcStr<CH>: Unicode {}
119
120impl<DT, V: OdbcVersion> Ansi for MaybeUninit<RefSQLHDESC<'_, DT, V>> {}
121impl<DT, V: OdbcVersion> Unicode for MaybeUninit<RefSQLHDESC<'_, DT, V>> {}
122
123impl<DT, V: OdbcVersion> Ansi for MaybeUninit<RefUnsafeSQLHDESC<'_, DT, V>> {}
124impl<DT, V: OdbcVersion> Unicode for MaybeUninit<RefUnsafeSQLHDESC<'_, DT, V>> {}
125
126impl<DT, V: OdbcVersion> Ansi for Option<&SQLHDESC<'_, DT, V>> {}
127impl<DT, V: OdbcVersion> Unicode for Option<&SQLHDESC<'_, DT, V>> {}
128
129impl<DT, V: OdbcVersion> Ansi for Option<&UnsafeSQLHDESC<'_, DT, V>> {}
130impl<DT, V: OdbcVersion> Unicode for Option<&UnsafeSQLHDESC<'_, DT, V>> {}