Skip to content
This repository was archived by the owner on Sep 1, 2026. It is now read-only.

Commit 2c83ea8

Browse files
committed
WIP
1 parent cc29910 commit 2c83ea8

7 files changed

Lines changed: 153 additions & 37 deletions

File tree

src/conditional.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl<'a> BuildCondition<'a> for Condition<'a> {
333333
Value::Null(NullType::Choice) => write!(writer, "NULL"),
334334

335335
_ => {
336-
lookup.push(*value);
336+
lookup.push(value.clone());
337337
match dialect {
338338
#[cfg(feature = "sqlite")]
339339
DBImpl::SQLite => {

src/cows.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//! Alternate [`Cow`]s which are covariant over their second argument
2+
3+
use std::borrow::Cow;
4+
use std::ops::Deref;
5+
6+
/// [`Cow<'a, [T]>`](Cow) which is covariant over `T`.
7+
#[derive(Clone, Debug, PartialEq)]
8+
pub enum VecCow<'a, T> {
9+
/// Borrowed data
10+
Borrowed(&'a [T]),
11+
12+
/// Owned data
13+
Owned(Vec<T>),
14+
}
15+
16+
impl<'a, T> Deref for VecCow<'a, T> {
17+
type Target = [T];
18+
19+
fn deref(&self) -> &[T] {
20+
match self {
21+
VecCow::Borrowed(slice) => slice,
22+
VecCow::Owned(vec) => vec,
23+
}
24+
}
25+
}
26+
27+
impl<'a, T> From<Cow<'a, [T]>> for VecCow<'a, T>
28+
where
29+
T: Clone,
30+
{
31+
fn from(value: Cow<'a, [T]>) -> Self {
32+
match value {
33+
Cow::Borrowed(x) => Self::Borrowed(x),
34+
Cow::Owned(x) => Self::Owned(x),
35+
}
36+
}
37+
}
38+
39+
impl<'a, T> From<&'a [T]> for VecCow<'a, T> {
40+
fn from(value: &'a [T]) -> Self {
41+
Self::Borrowed(value)
42+
}
43+
}
44+
45+
impl<'a, T> From<Vec<T>> for VecCow<'a, T> {
46+
fn from(value: Vec<T>) -> Self {
47+
Self::Owned(value)
48+
}
49+
}
50+
51+
/// `Cow<'a, T>` which is covariant over `T`.
52+
#[derive(Clone, Debug, PartialEq)]
53+
pub enum RefCow<'a, T> {
54+
/// Borrowed data
55+
Borrowed(&'a T),
56+
57+
/// Owned data
58+
Owned(T),
59+
}
60+
61+
impl<'a, T> Deref for RefCow<'a, T> {
62+
type Target = T;
63+
64+
fn deref(&self) -> &T {
65+
match self {
66+
Self::Borrowed(x) => x,
67+
Self::Owned(x) => x,
68+
}
69+
}
70+
}
71+
72+
impl<'a, T> From<Cow<'a, T>> for RefCow<'a, T>
73+
where
74+
T: Clone,
75+
{
76+
fn from(value: Cow<'a, T>) -> Self {
77+
match value {
78+
Cow::Borrowed(x) => Self::Borrowed(x),
79+
Cow::Owned(x) => Self::Owned(x),
80+
}
81+
}
82+
}
83+
84+
impl<'a, T> From<&'a T> for RefCow<'a, T> {
85+
fn from(value: &'a T) -> Self {
86+
Self::Borrowed(value)
87+
}
88+
}
89+
90+
impl<'a, T> From<T> for RefCow<'a, T> {
91+
fn from(value: T) -> Self {
92+
Self::Owned(value)
93+
}
94+
}

src/insert.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ impl<'post_build> Insert<'post_build> for InsertImpl<'_, 'post_build> {
198198
Value::Choice(c) => write!(s, "{}", postgres::fmt(c)).unwrap(),
199199
Value::Null(NullType::Choice) => write!(s, "NULL").unwrap(),
200200
_ => {
201-
d.lookup.push(*y);
201+
d.lookup.push(y.clone());
202202
write!(s, "${}", d.lookup.len()).unwrap();
203203
}
204204
}

src/join_table.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use std::borrow::Cow;
21
use std::fmt::{Display, Formatter, Write};
32

43
use crate::conditional::{BuildCondition, Condition};
4+
use crate::cows::RefCow;
55
use crate::value::Value;
66
use crate::DBImpl;
77

@@ -79,7 +79,16 @@ pub struct JoinTableData<'until_build, 'post_query> {
7979
/// Alias for the join table
8080
pub join_alias: &'until_build str,
8181
/// Condition to apply the join on
82-
pub join_condition: Cow<'until_build, Condition<'post_query>>,
82+
pub join_condition: RefCow<'until_build, Condition<'post_query>>,
83+
}
84+
85+
/// [`JoinTableData`] should not be invariant over `'post_query`
86+
#[expect(unused)]
87+
fn test_variance<'a, 'b, 'c>(x: JoinTableData<'c, 'a>) -> JoinTableData<'c, 'b>
88+
where
89+
'a: 'b,
90+
{
91+
x
8392
}
8493

8594
/**

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ pub mod update;
4444
/// Implementation of supported datatypes
4545
pub mod value;
4646

47+
pub mod cows;
4748
mod db_specific;
4849

49-
use std::borrow::Cow;
50-
5150
use rorm_declaration::imr::{Annotation, DbType};
5251

5352
use crate::aggregation::SelectAggregator;
5453
use crate::alter_table::{AlterTable, AlterTableData, AlterTableImpl, AlterTableOperation};
5554
use crate::conditional::Condition;
55+
use crate::cows::RefCow;
5656
#[cfg(feature = "postgres")]
5757
use crate::create_column::CreateColumnPostgresData;
5858
#[cfg(feature = "sqlite")]
@@ -417,7 +417,7 @@ impl DBImpl {
417417
join_type: JoinType,
418418
table_name: &'until_build str,
419419
join_alias: &'until_build str,
420-
join_condition: Cow<'until_build, Condition<'post_query>>,
420+
join_condition: RefCow<'until_build, Condition<'post_query>>,
421421
) -> JoinTableImpl<'until_build, 'post_query> {
422422
let d = JoinTableData {
423423
join_type,

src/update.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl<'until_build, 'post_build> Update<'until_build, 'post_build>
174174
let update_index = d.updates.len() - 1;
175175
for (idx, (name, value)) in d.updates.into_iter().enumerate() {
176176
if let Value::Choice(c) = value {
177-
write!(s, "\"{name}\" = {}", postgres::fmt(c)).unwrap();
177+
write!(s, "\"{name}\" = {}", postgres::fmt(&c)).unwrap();
178178
} else if let Value::Null(NullType::Choice) = value {
179179
write!(s, "\"{name}\" = NULL").unwrap();
180180
} else {

src/value.rs

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
use std::borrow::Cow;
2+
13
use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
24
use time::{Date, OffsetDateTime, PrimitiveDateTime, Time};
35
use uuid::Uuid;
46

7+
use crate::cows::VecCow;
8+
59
/// This enum represents a [Null](Value::Null)'s type
610
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
711
pub enum NullType {
@@ -61,27 +65,27 @@ pub enum NullType {
6165
/**
6266
This enum represents a value
6367
*/
64-
#[derive(Copy, Clone, Debug, PartialEq)]
68+
#[derive(Clone, Debug, PartialEq)]
6569
pub enum Value<'a> {
6670
/// null representation
6771
Null(NullType),
6872
/// Representation of an identifier, e.g. a column.
6973
/// This variant will not be escaped, so do not
7074
/// pass unchecked data to it.
7175
#[deprecated(note = "Is this still used?")]
72-
Ident(&'a str),
76+
Ident(Cow<'a, str>),
7377
/// Representation of a column name with
7478
/// an optional table name
7579
Column {
7680
/// Name of the table
77-
table_name: Option<&'a str>,
81+
table_name: Option<Cow<'a, str>>,
7882
/// Name of the column
79-
column_name: &'a str,
83+
column_name: Cow<'a, str>,
8084
},
8185
/// Representation of choices
82-
Choice(&'a str),
86+
Choice(Cow<'a, str>),
8387
/// String representation
84-
String(&'a str),
88+
String(Cow<'a, str>),
8589
/// i64 representation
8690
I64(i64),
8791
/// i32 representation
@@ -95,7 +99,7 @@ pub enum Value<'a> {
9599
/// f32 representation
96100
F32(f32),
97101
/// binary representation
98-
Binary(&'a [u8]),
102+
Binary(Cow<'a, [u8]>),
99103
/// chrono's Naive Time representation
100104
ChronoNaiveTime(NaiveTime),
101105
/// chrono's Naive Date representation
@@ -131,73 +135,82 @@ pub enum Value<'a> {
131135
IpNetwork(ipnetwork::IpNetwork),
132136
/// Bit vec representation
133137
#[cfg(feature = "postgres-only")]
134-
BitVec(&'a bit_vec::BitVec),
138+
BitVec(Cow<'a, bit_vec::BitVec>),
135139

136140
/// null representation
137141
#[cfg(feature = "postgres-only")]
138142
ArrayNull(NullType),
139143
/// String representation
140144
#[cfg(feature = "postgres-only")]
141-
ArrayString(&'a [&'a str]),
145+
ArrayString(VecCow<'a, Cow<'a, str>>),
142146
/// i64 representation
143147
#[cfg(feature = "postgres-only")]
144-
ArrayI64(&'a [i64]),
148+
ArrayI64(VecCow<'a, i64>),
145149
/// i32 representation
146150
#[cfg(feature = "postgres-only")]
147-
ArrayI32(&'a [i32]),
151+
ArrayI32(VecCow<'a, i32>),
148152
/// i16 representation
149153
#[cfg(feature = "postgres-only")]
150-
ArrayI16(&'a [i16]),
154+
ArrayI16(VecCow<'a, i16>),
151155
/// Bool representation
152156
#[cfg(feature = "postgres-only")]
153-
ArrayBool(&'a [bool]),
157+
ArrayBool(VecCow<'a, bool>),
154158
/// f64 representation
155159
#[cfg(feature = "postgres-only")]
156-
ArrayF64(&'a [f64]),
160+
ArrayF64(VecCow<'a, f64>),
157161
/// f32 representation
158162
#[cfg(feature = "postgres-only")]
159-
ArrayF32(&'a [f32]),
163+
ArrayF32(VecCow<'a, f32>),
160164
/// binary representation
161165
#[cfg(feature = "postgres-only")]
162-
ArrayBinary(&'a [&'a [u8]]),
166+
ArrayBinary(VecCow<'a, Cow<'a, [u8]>>),
163167
/// chrono's Naive Time representation
164168
#[cfg(feature = "postgres-only")]
165-
ArrayChronoNaiveTime(&'a [NaiveTime]),
169+
ArrayChronoNaiveTime(VecCow<'a, NaiveTime>),
166170
/// chrono's Naive Date representation
167171
#[cfg(feature = "postgres-only")]
168-
ArrayChronoNaiveDate(&'a [NaiveDate]),
172+
ArrayChronoNaiveDate(VecCow<'a, NaiveDate>),
169173
/// chrono's Naive DateTime representation
170174
#[cfg(feature = "postgres-only")]
171-
ArrayChronoNaiveDateTime(&'a [NaiveDateTime]),
175+
ArrayChronoNaiveDateTime(VecCow<'a, NaiveDateTime>),
172176
/// chrono's Timezone aware datetime
173177
#[cfg(feature = "postgres-only")]
174-
ArrayChronoDateTime(&'a [DateTime<Utc>]),
178+
ArrayChronoDateTime(VecCow<'a, DateTime<Utc>>),
175179
/// time's date representation
176180
#[cfg(feature = "postgres-only")]
177-
ArrayTimeDate(&'a [Date]),
181+
ArrayTimeDate(VecCow<'a, Date>),
178182
/// time's time representation
179183
#[cfg(feature = "postgres-only")]
180-
ArrayTimeTime(&'a [Time]),
184+
ArrayTimeTime(VecCow<'a, Time>),
181185
/// time's offset datetime representation
182186
#[cfg(feature = "postgres-only")]
183-
ArrayTimeOffsetDateTime(&'a [OffsetDateTime]),
187+
ArrayTimeOffsetDateTime(VecCow<'a, OffsetDateTime>),
184188
/// time's primitive datetime representation
185189
#[cfg(feature = "postgres-only")]
186-
ArrayTimePrimitiveDateTime(&'a [PrimitiveDateTime]),
190+
ArrayTimePrimitiveDateTime(VecCow<'a, PrimitiveDateTime>),
187191
/// Uuid representation
188192
#[cfg(feature = "postgres-only")]
189-
ArrayUuid(&'a [Uuid]),
193+
ArrayUuid(VecCow<'a, Uuid>),
190194
/// serde_json's Value representation
191195
#[cfg(feature = "postgres-only")]
192-
ArrayJsonValue(&'a [&'a serde_json::Value]),
196+
ArrayJsonValue(VecCow<'a, &'a serde_json::Value>),
193197

194198
/// Mac address representation
195199
#[cfg(feature = "postgres-only")]
196-
ArrayMacAddress(&'a [mac_address::MacAddress]),
200+
ArrayMacAddress(VecCow<'a, mac_address::MacAddress>),
197201
/// IP network presentation
198202
#[cfg(feature = "postgres-only")]
199-
ArrayIpNetwork(&'a [ipnetwork::IpNetwork]),
203+
ArrayIpNetwork(VecCow<'a, ipnetwork::IpNetwork>),
200204
/// Bit vec representation
201205
#[cfg(feature = "postgres-only")]
202-
ArrayBitVec(&'a [&'a bit_vec::BitVec]),
206+
ArrayBitVec(VecCow<'a, Cow<'a, bit_vec::BitVec>>),
207+
}
208+
209+
/// [`Value`] should be covariant over `'a`
210+
#[expect(unused)]
211+
fn test_variance<'a, 'b>(x: Value<'a>) -> Value<'b>
212+
where
213+
'a: 'b,
214+
{
215+
x
203216
}

0 commit comments

Comments
 (0)