Skip to content

Commit 4273316

Browse files
authored
feat: crdt type create & convert (#461)
* feat: add convert for any * chore: disable add to project action * feat: add content convert & sub array support * feat: fix item ref for ytype * fix: test case * chore: cleanup type convertor
1 parent 6b584a2 commit 4273316

File tree

11 files changed

+286
-106
lines changed

11 files changed

+286
-106
lines changed

.github/workflows/add-to-project.yml

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
name: Add to GitHub projects
22

3-
on:
4-
issues:
5-
types:
6-
- opened
7-
pull_request_target:
8-
types:
9-
- opened
10-
- reopened
3+
# on:
4+
# issues:
5+
# types:
6+
# - opened
7+
# pull_request_target:
8+
# types:
9+
# - opened
10+
# - reopened
1111

1212
jobs:
13-
add-to-project:
14-
name: Add issues and pull requests
15-
runs-on: ubuntu-latest
16-
steps:
17-
- uses: actions/[email protected]
18-
with:
19-
# You can target a repository in a different organization
20-
# to the issue
21-
project-url: https://github.com/orgs/toeverything/projects/10
22-
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
23-
# labeled: bug, needs-triage
24-
# label-operator: OR
13+
add-to-project:
14+
name: Add issues and pull requests
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/[email protected]
18+
with:
19+
# You can target a repository in a different organization
20+
# to the issue
21+
project-url: https://github.com/orgs/toeverything/projects/10
22+
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
23+
# labeled: bug, needs-triage
24+
# label-operator: OR

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libs/jwst-codec/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ arbitrary = { version = "1.3.0", features = ["derive"] }
2525
ordered-float = { version = "3.6.0", features = ["arbitrary"] }
2626

2727
[dev-dependencies]
28+
assert-json-diff = "2.0.2"
2829
criterion = { version = "0.5.1", features = ["html_reports"] }
29-
lib0 = "0.16.5"
30+
lib0 = { version = "0.16.5", features = ["lib0-serde"] }
3031
ordered-float = { version = "3.6.0", features = ["proptest"] }
3132
path-ext = "0.1.0"
3233
proptest = "1.1.0"

libs/jwst-codec/src/doc/codec/any.rs

Lines changed: 156 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -112,112 +112,142 @@ impl<W: CrdtWriter> CrdtWrite<W> for Any {
112112
}
113113
}
114114

115-
// TODO: impl for Any::Undefined
116-
impl From<String> for Any {
117-
fn from(s: String) -> Self {
118-
Any::String(s)
115+
impl Any {
116+
fn read_key_value<R: CrdtReader>(reader: &mut R) -> JwstCodecResult<(String, Any)> {
117+
let key = reader.read_var_string()?;
118+
let value = Self::read(reader)?;
119+
120+
Ok((key, value))
119121
}
120-
}
121122

122-
impl From<&str> for Any {
123-
fn from(s: &str) -> Self {
124-
Any::from(s.to_string())
123+
fn write_key_value<W: CrdtWriter>(writer: &mut W, key: &str, value: &Any) -> JwstCodecResult {
124+
writer.write_var_string(key)?;
125+
value.write(writer)?;
126+
127+
Ok(())
125128
}
126-
}
127129

128-
impl<T: Into<Any>> From<Option<T>> for Any {
129-
fn from(value: Option<T>) -> Self {
130-
if let Some(val) = value {
131-
val.into()
132-
} else {
133-
Any::Null
134-
}
130+
pub(crate) fn read_multiple<R: CrdtReader>(reader: &mut R) -> JwstCodecResult<Vec<Any>> {
131+
let len = reader.read_var_u64()?;
132+
let any = (0..len)
133+
.map(|_| Any::read(reader))
134+
.collect::<Result<Vec<_>, _>>()?;
135+
136+
Ok(any)
135137
}
136-
}
137138

138-
impl From<u64> for Any {
139-
fn from(value: u64) -> Self {
140-
Any::Integer(value)
139+
pub(crate) fn write_multiple<W: CrdtWriter>(writer: &mut W, any: &[Any]) -> JwstCodecResult {
140+
writer.write_var_u64(any.len() as u64)?;
141+
for value in any {
142+
value.write(writer)?;
143+
}
144+
145+
Ok(())
141146
}
142147
}
143148

144-
impl From<OrderedFloat<f32>> for Any {
145-
fn from(value: OrderedFloat<f32>) -> Self {
146-
Any::Float32(value)
147-
}
149+
macro_rules! impl_primitive_from {
150+
(unsigned, $($ty: ty),*) => {
151+
$(
152+
impl From<$ty> for Any {
153+
fn from(value: $ty) -> Self {
154+
Self::Integer(value.into())
155+
}
156+
}
157+
)*
158+
};
159+
(signed, $($ty: ty),*) => {
160+
$(
161+
impl From<$ty> for Any {
162+
fn from(value: $ty) -> Self {
163+
Self::BigInt64(value.into())
164+
}
165+
}
166+
)*
167+
};
168+
(string, $($ty: ty),*) => {
169+
$(
170+
impl From<$ty> for Any {
171+
fn from(value: $ty) -> Self {
172+
Self::String(value.into())
173+
}
174+
}
175+
)*
176+
};
148177
}
149178

150-
impl From<OrderedFloat<f64>> for Any {
151-
fn from(value: OrderedFloat<f64>) -> Self {
152-
Any::Float64(value)
179+
impl_primitive_from!(unsigned, u8, u16, u32, u64);
180+
impl_primitive_from!(signed, i8, i16, i32, i64);
181+
impl_primitive_from!(string, String, &str);
182+
183+
impl From<f32> for Any {
184+
fn from(value: f32) -> Self {
185+
Self::Float32(value.into())
153186
}
154187
}
155188

156-
impl From<i64> for Any {
157-
fn from(value: i64) -> Self {
158-
Any::BigInt64(value)
189+
impl From<f64> for Any {
190+
fn from(value: f64) -> Self {
191+
Self::Float64(value.into())
159192
}
160193
}
161194

162195
impl From<bool> for Any {
163196
fn from(value: bool) -> Self {
164197
if value {
165-
Any::True
198+
Self::True
166199
} else {
167-
Any::False
200+
Self::False
168201
}
169202
}
170203
}
171204

172-
impl From<HashMap<String, Any>> for Any {
173-
fn from(value: HashMap<String, Any>) -> Self {
174-
Any::Object(value)
205+
impl FromIterator<Any> for Any {
206+
fn from_iter<I: IntoIterator<Item = Any>>(iter: I) -> Self {
207+
Self::Array(iter.into_iter().collect())
175208
}
176209
}
177210

178-
impl From<Vec<Any>> for Any {
179-
fn from(value: Vec<Any>) -> Self {
180-
Any::Array(value)
211+
impl<'a> FromIterator<&'a Any> for Any {
212+
fn from_iter<I: IntoIterator<Item = &'a Any>>(iter: I) -> Self {
213+
Self::Array(iter.into_iter().cloned().collect())
181214
}
182215
}
183216

184-
impl From<Vec<u8>> for Any {
185-
fn from(value: Vec<u8>) -> Self {
186-
Any::Binary(value)
217+
impl FromIterator<(String, Any)> for Any {
218+
fn from_iter<I: IntoIterator<Item = (String, Any)>>(iter: I) -> Self {
219+
let mut map = HashMap::new();
220+
map.extend(iter);
221+
Self::Object(map)
187222
}
188223
}
189224

190-
impl Any {
191-
fn read_key_value<R: CrdtReader>(reader: &mut R) -> JwstCodecResult<(String, Any)> {
192-
let key = reader.read_var_string()?;
193-
let value = Self::read(reader)?;
194-
195-
Ok((key, value))
225+
impl From<HashMap<String, Any>> for Any {
226+
fn from(value: HashMap<String, Any>) -> Self {
227+
Self::Object(value)
196228
}
229+
}
197230

198-
fn write_key_value<W: CrdtWriter>(writer: &mut W, key: &str, value: &Any) -> JwstCodecResult {
199-
writer.write_var_string(key)?;
200-
value.write(writer)?;
201-
202-
Ok(())
231+
impl From<Vec<u8>> for Any {
232+
fn from(value: Vec<u8>) -> Self {
233+
Self::Binary(value)
203234
}
235+
}
204236

205-
pub(crate) fn read_multiple<R: CrdtReader>(reader: &mut R) -> JwstCodecResult<Vec<Any>> {
206-
let len = reader.read_var_u64()?;
207-
let any = (0..len)
208-
.map(|_| Any::read(reader))
209-
.collect::<Result<Vec<_>, _>>()?;
210-
211-
Ok(any)
237+
impl From<&[u8]> for Any {
238+
fn from(value: &[u8]) -> Self {
239+
Self::Binary(value.into())
212240
}
241+
}
213242

214-
pub(crate) fn write_multiple<W: CrdtWriter>(writer: &mut W, any: &[Any]) -> JwstCodecResult {
215-
writer.write_var_u64(any.len() as u64)?;
216-
for value in any {
217-
value.write(writer)?;
243+
// TODO: impl for Any::Undefined
244+
impl<T: Into<Any>> From<Option<T>> for Any {
245+
fn from(value: Option<T>) -> Self {
246+
if let Some(val) = value {
247+
val.into()
248+
} else {
249+
Any::Null
218250
}
219-
220-
Ok(())
221251
}
222252
}
223253

@@ -310,4 +340,65 @@ mod tests {
310340
}
311341
}
312342
}
343+
344+
#[test]
345+
fn test_convert_to_any() {
346+
let any: Vec<Any> = vec![
347+
42u8.into(),
348+
42u16.into(),
349+
42u32.into(),
350+
42u64.into(),
351+
114.514f32.into(),
352+
1919.810f64.into(),
353+
(-42i8).into(),
354+
(-42i16).into(),
355+
(-42i32).into(),
356+
(-42i64).into(),
357+
false.into(),
358+
true.into(),
359+
"JWST".to_string().into(),
360+
"OctoBase".into(),
361+
vec![1u8, 9, 1, 9].into(),
362+
(&[8u8, 1, 0][..]).into(),
363+
[Any::True, 42u8.into()].iter().collect(),
364+
];
365+
assert_eq!(
366+
any,
367+
vec![
368+
Any::Integer(42),
369+
Any::Integer(42),
370+
Any::Integer(42),
371+
Any::Integer(42),
372+
Any::Float32(114.514.into()),
373+
Any::Float64(1919.810.into()),
374+
Any::BigInt64(-42),
375+
Any::BigInt64(-42),
376+
Any::BigInt64(-42),
377+
Any::BigInt64(-42),
378+
Any::False,
379+
Any::True,
380+
Any::String("JWST".to_string()),
381+
Any::String("OctoBase".to_string()),
382+
Any::Binary(vec![1, 9, 1, 9]),
383+
Any::Binary(vec![8, 1, 0]),
384+
Any::Array(vec![Any::True, Any::Integer(42)])
385+
]
386+
);
387+
388+
assert_eq!(
389+
vec![("key".to_string(), 10u64.into())]
390+
.into_iter()
391+
.collect::<Any>(),
392+
Any::Object(HashMap::from_iter(vec![(
393+
"key".to_string(),
394+
Any::Integer(10)
395+
)]))
396+
);
397+
398+
let any: Any = 10u64.into();
399+
assert_eq!(
400+
[any].iter().collect::<Any>(),
401+
Any::Array(vec![Any::Integer(10)])
402+
);
403+
}
313404
}

libs/jwst-codec/src/doc/codec/content.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,49 @@ impl Content {
329329

330330
s.split_at(utf_8_offset)
331331
}
332+
333+
pub fn as_array(&self) -> Option<Array> {
334+
if let Self::Type(type_ref) = self {
335+
return Array::try_from(type_ref.clone()).ok();
336+
}
337+
None
338+
}
332339
}
333340

341+
macro_rules! impl_primitive_from {
342+
(any => $($ty:ty),* $(,)?) => {
343+
$(
344+
impl From<$ty> for Content {
345+
fn from(value: $ty) -> Self {
346+
Self::Any(vec![value.into()])
347+
}
348+
}
349+
)*
350+
};
351+
(raw => $($ty:ty: $v:ident),* $(,)?) => {
352+
$(
353+
impl From<$ty> for Content {
354+
fn from(value: $ty) -> Self {
355+
Self::$v(value)
356+
}
357+
}
358+
)*
359+
};
360+
(type_ref => $($ty:ty),* $(,)?) => {
361+
$(
362+
impl From<$ty> for Content {
363+
fn from(type_ref: $ty) -> Self {
364+
Self::Type(type_ref.as_inner().clone())
365+
}
366+
}
367+
)*
368+
}
369+
}
370+
371+
impl_primitive_from! { any => u8, u16, u32, u64, i8, i16, i32, i64, String, &str, f32, f64, bool }
372+
impl_primitive_from! { raw => Vec<u8>: Binary, YTypeRef: Type }
373+
impl_primitive_from! { type_ref => Array, Text }
374+
334375
#[cfg(test)]
335376
mod tests {
336377
use super::*;

0 commit comments

Comments
 (0)