Internal representation = base64 string
This commit is contained in:
parent
41021f398f
commit
22af56b059
9 changed files with 19 additions and 21 deletions
automerge-backend/src
automerge-frontend
automerge-protocol/src
|
@ -574,12 +574,7 @@ impl ValEncoder {
|
|||
amp::ScalarValue::Null => self.len.append_value(VALUE_TYPE_NULL),
|
||||
amp::ScalarValue::Boolean(true) => self.len.append_value(VALUE_TYPE_TRUE),
|
||||
amp::ScalarValue::Boolean(false) => self.len.append_value(VALUE_TYPE_FALSE),
|
||||
amp::ScalarValue::Bytes(bytes) => {
|
||||
let len = bytes.len();
|
||||
self.raw.extend(bytes);
|
||||
self.len.append_value(len << 4 | VALUE_TYPE_BYTES)
|
||||
}
|
||||
amp::ScalarValue::Str(s) => {
|
||||
amp::ScalarValue::Str(s) | amp::ScalarValue::Bytes(s) => {
|
||||
let bytes = s.as_bytes();
|
||||
let len = bytes.len();
|
||||
self.raw.extend(bytes);
|
||||
|
|
|
@ -19,6 +19,7 @@ thiserror = "1.0.16"
|
|||
im-rc = "15.0.0"
|
||||
unicode-segmentation = "1.7.1"
|
||||
arbitrary = { version = "1", features = ["derive"], optional = true }
|
||||
base64 = "0.13.0"
|
||||
|
||||
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
|
||||
getrandom = { version = "0.2.2", features=["js"] }
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::{error::Error, fmt};
|
|||
|
||||
use automerge_protocol as amp;
|
||||
use automerge_protocol::ObjectId;
|
||||
use base64::DecodeError;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{value::Value, Path};
|
||||
|
@ -80,6 +81,8 @@ pub enum InvalidPatch {
|
|||
DiffEditWithHeadElemId,
|
||||
#[error("Value diff containing cursor")]
|
||||
ValueDiffContainedCursor,
|
||||
#[error("Base64 decoding error: {0} for string: \"{1}\"")]
|
||||
InvalidBase64(DecodeError, String),
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::{collections::HashMap, convert::TryInto};
|
|||
|
||||
use amp::{MapDiff, ObjectId};
|
||||
use automerge_protocol as amp;
|
||||
use base64;
|
||||
|
||||
use crate::{error, Cursor, Path, PathElement, Primitive, Value};
|
||||
|
||||
|
@ -508,7 +509,10 @@ impl StateTreeValue {
|
|||
match diff.diff {
|
||||
amp::Diff::Value(v) => {
|
||||
let value = match v {
|
||||
amp::ScalarValue::Bytes(b) => Primitive::Bytes(b.clone()),
|
||||
amp::ScalarValue::Bytes(b) => match base64::decode(b) {
|
||||
Ok(bytes) => Primitive::Bytes(bytes),
|
||||
Err(e) => return Err(error::InvalidPatch::InvalidBase64(e, b.clone())),
|
||||
},
|
||||
amp::ScalarValue::Str(s) => Primitive::Str(s.clone()),
|
||||
amp::ScalarValue::Int(i) => Primitive::Int(*i),
|
||||
amp::ScalarValue::Uint(u) => Primitive::Uint(*u),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::{cmp::Ordering, iter::Iterator};
|
||||
|
||||
use automerge_protocol as amp;
|
||||
use base64;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use super::{
|
||||
|
@ -676,7 +677,7 @@ where
|
|||
_ => Cursors::new(),
|
||||
};
|
||||
let value = match primitive {
|
||||
Primitive::Bytes(b) => amp::ScalarValue::Bytes(b.clone()),
|
||||
Primitive::Bytes(b) => amp::ScalarValue::Bytes(base64::encode(b)),
|
||||
Primitive::Str(s) => amp::ScalarValue::Str(s.clone()),
|
||||
Primitive::Int(i) => amp::ScalarValue::Int(*i),
|
||||
Primitive::Uint(u) => amp::ScalarValue::Uint(*u),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::{borrow::Borrow, collections::HashMap};
|
||||
|
||||
use automerge_protocol as amp;
|
||||
use base64;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize, Clone, Debug, PartialEq)]
|
||||
|
@ -66,7 +67,7 @@ impl From<Cursor> for Value {
|
|||
impl From<&Primitive> for amp::ScalarValue {
|
||||
fn from(p: &Primitive) -> Self {
|
||||
match p {
|
||||
Primitive::Bytes(b) => amp::ScalarValue::Bytes(b.clone()),
|
||||
Primitive::Bytes(b) => amp::ScalarValue::Bytes(base64::encode(b)),
|
||||
Primitive::Str(s) => amp::ScalarValue::Str(s.clone()),
|
||||
Primitive::Int(i) => amp::ScalarValue::Int(*i),
|
||||
Primitive::Uint(u) => amp::ScalarValue::Uint(*u),
|
||||
|
@ -182,11 +183,7 @@ impl Value {
|
|||
),
|
||||
Primitive::Uint(n) => serde_json::Value::Number(serde_json::Number::from(*n)),
|
||||
Primitive::Int(n) => serde_json::Value::Number(serde_json::Number::from(*n)),
|
||||
Primitive::Bytes(b) => serde_json::Value::Array(
|
||||
b.iter()
|
||||
.map(|byte| serde_json::Value::Number(serde_json::Number::from(*byte)))
|
||||
.collect(),
|
||||
),
|
||||
Primitive::Bytes(b) => serde_json::Value::String(base64::encode(b)),
|
||||
Primitive::Str(s) => serde_json::Value::String(s.to_string()),
|
||||
Primitive::Boolean(b) => serde_json::Value::Bool(*b),
|
||||
Primitive::Counter(c) => serde_json::Value::Number(serde_json::Number::from(*c)),
|
||||
|
|
|
@ -107,7 +107,7 @@ fn test_set_bytes() {
|
|||
hash: None,
|
||||
deps: Vec::new(),
|
||||
operations: vec![amp::Op {
|
||||
action: amp::OpType::Set(amp::ScalarValue::Bytes(vec![1, 2, 3])),
|
||||
action: amp::OpType::Set(amp::ScalarValue::Bytes("AQID".into())),
|
||||
obj: "_root".try_into().unwrap(),
|
||||
key: "bird".into(),
|
||||
insert: false,
|
||||
|
|
|
@ -222,7 +222,7 @@ impl DataType {
|
|||
#[derive(Serialize, PartialEq, Debug, Clone)]
|
||||
#[serde(untagged)]
|
||||
pub enum ScalarValue {
|
||||
Bytes(Vec<u8>),
|
||||
Bytes(String),
|
||||
Str(String),
|
||||
Int(i64),
|
||||
Uint(u64),
|
||||
|
@ -254,7 +254,7 @@ impl ScalarValue {
|
|||
(DataType::Bytes, ScalarValue::Bytes(bytes)) => Ok(ScalarValue::Bytes(bytes.clone())),
|
||||
(DataType::Bytes, v) => Err(error::InvalidScalarValue {
|
||||
raw_value: self.clone(),
|
||||
expected: "a vec of bytes".to_string(),
|
||||
expected: "a base64 encoded string of bytes".to_string(),
|
||||
unexpected: v.to_string(),
|
||||
datatype,
|
||||
}),
|
||||
|
|
|
@ -171,10 +171,7 @@ impl<'de> Deserialize<'de> for Op {
|
|||
Some(ScalarValue::F32(n)) => Ok(OpType::Inc(n as i64)),
|
||||
Some(ScalarValue::Counter(n)) => Ok(OpType::Inc(n)),
|
||||
Some(ScalarValue::Timestamp(n)) => Ok(OpType::Inc(n)),
|
||||
Some(ScalarValue::Bytes(b)) => {
|
||||
Err(Error::invalid_value(Unexpected::Bytes(&b), &"a number"))
|
||||
}
|
||||
Some(ScalarValue::Str(s)) => {
|
||||
Some(ScalarValue::Str(s) | ScalarValue::Bytes(s)) => {
|
||||
Err(Error::invalid_value(Unexpected::Str(&s), &"a number"))
|
||||
}
|
||||
Some(ScalarValue::Boolean(b)) => {
|
||||
|
|
Loading…
Add table
Reference in a new issue