mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: number sort (#2570)
* chore: remove sign * fix: sort number * chore: update patch * ci: fix dart test * chore: fmt
This commit is contained in:
parent
bb681bdd1e
commit
6c31cf9555
@ -151,7 +151,6 @@ class RowList {
|
||||
(rowInfo) => rowInfo.rowPB.id == rowId,
|
||||
);
|
||||
if (index != -1) {
|
||||
assert(index == oldIndex);
|
||||
final rowInfo = remove(rowId)!.rowInfo;
|
||||
insert(newIndex, rowInfo);
|
||||
}
|
||||
|
@ -34,12 +34,12 @@ default = ["custom-protocol"]
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
|
||||
#collab = { path = "../../AppFlowy-Collab/collab" }
|
||||
#collab-folder = { path = "../../AppFlowy-Collab/collab-folder" }
|
||||
|
108
frontend/rust-lib/Cargo.lock
generated
108
frontend/rust-lib/Cargo.lock
generated
@ -85,7 +85,7 @@ checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
||||
[[package]]
|
||||
name = "appflowy-integrate"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"collab",
|
||||
"collab-database",
|
||||
@ -574,9 +574,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.64.0"
|
||||
version = "0.65.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"
|
||||
checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
@ -584,12 +584,13 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"peeking_take_while",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -883,7 +884,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -900,7 +901,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-client-ws"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab-sync",
|
||||
@ -918,7 +919,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -942,7 +943,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -954,7 +955,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -971,7 +972,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -989,7 +990,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@ -1009,7 +1010,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1035,7 +1036,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-sync"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7a2e97#7a2e97d9bfe746f5db18753ab0b59347ec5bf23f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
@ -1817,6 +1818,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serial_test",
|
||||
"tempdir",
|
||||
"thread-id",
|
||||
"tokio",
|
||||
]
|
||||
@ -1899,6 +1901,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.28"
|
||||
@ -2584,9 +2592,9 @@ checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
|
||||
|
||||
[[package]]
|
||||
name = "librocksdb-sys"
|
||||
version = "0.10.0+7.9.2"
|
||||
version = "0.11.0+8.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fe4d5874f5ff2bc616e55e8c6086d478fcda13faf9495768a4aa1c22042d30b"
|
||||
checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"bzip2-sys",
|
||||
@ -3235,6 +3243,16 @@ version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ceca8aaf45b5c46ec7ed39fff75f57290368c1846d33d24a122ca81416ab058"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "0.1.5"
|
||||
@ -3475,6 +3493,19 @@ dependencies = [
|
||||
"scheduled-thread-pool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
dependencies = [
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.3.1",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
@ -3520,6 +3551,21 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
@ -3578,6 +3624,15 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
@ -3639,6 +3694,15 @@ version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rend"
|
||||
version = "0.4.0"
|
||||
@ -3727,9 +3791,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rocksdb"
|
||||
version = "0.20.1"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "015439787fce1e75d55f279078d33ff14b4af5d93d995e8838ee4631301c8a99"
|
||||
checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"librocksdb-sys",
|
||||
@ -4242,6 +4306,16 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "tempdir"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||
dependencies = [
|
||||
"rand 0.4.6",
|
||||
"remove_dir_all",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.5.0"
|
||||
|
@ -32,11 +32,11 @@ opt-level = 3
|
||||
incremental = false
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7a2e97" }
|
||||
|
||||
#collab = { path = "../AppFlowy-Collab/collab" }
|
||||
#collab-folder = { path = "../AppFlowy-Collab/collab-folder" }
|
||||
|
@ -84,7 +84,7 @@ fn create_log_filter(level: String, with_crates: Vec<String>) -> String {
|
||||
filters.push(format!("flowy_core={}", level));
|
||||
filters.push(format!("flowy_folder2={}", level));
|
||||
filters.push(format!("collab_folder={}", level));
|
||||
// filters.push(format!("collab_persistence={}", level));
|
||||
filters.push(format!("collab_persistence={}", level));
|
||||
filters.push(format!("collab_database={}", level));
|
||||
filters.push(format!("collab_plugins={}", level));
|
||||
filters.push(format!("appflowy_integrate={}", level));
|
||||
|
@ -13,9 +13,6 @@ pub struct NumberTypeOptionPB {
|
||||
#[pb(index = 3)]
|
||||
pub symbol: String,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub sign_positive: bool,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub name: String,
|
||||
}
|
||||
@ -26,7 +23,6 @@ impl From<NumberTypeOption> for NumberTypeOptionPB {
|
||||
format: data.format.into(),
|
||||
scale: data.scale,
|
||||
symbol: data.symbol,
|
||||
sign_positive: data.sign_positive,
|
||||
name: data.name,
|
||||
}
|
||||
}
|
||||
@ -38,7 +34,6 @@ impl From<NumberTypeOptionPB> for NumberTypeOption {
|
||||
format: data.format.into(),
|
||||
scale: data.scale,
|
||||
symbol: data.symbol,
|
||||
sign_positive: data.sign_positive,
|
||||
name: data.name,
|
||||
}
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ pub(crate) async fn get_cell_handler(
|
||||
data_result_ok(cell)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub(crate) async fn update_cell_handler(
|
||||
data: AFPluginData<CellChangesetPB>,
|
||||
manager: AFPluginState<Arc<DatabaseManager2>>,
|
||||
|
@ -58,7 +58,7 @@ pub trait CellDataChangeset: TypeOption {
|
||||
/// FieldType::SingleSelect => SelectOptionChangeset
|
||||
///
|
||||
/// cell_rev: It will be None if the cell does not contain any data.
|
||||
pub fn apply_cell_data_changeset<C: ToCellChangeset>(
|
||||
pub fn apply_cell_changeset<C: ToCellChangeset>(
|
||||
changeset: C,
|
||||
cell: Option<Cell>,
|
||||
field: &Field,
|
||||
@ -194,11 +194,11 @@ pub fn stringify_cell_data(
|
||||
}
|
||||
|
||||
pub fn insert_text_cell(s: String, field: &Field) -> Cell {
|
||||
apply_cell_data_changeset(s, None, field, None).unwrap()
|
||||
apply_cell_changeset(s, None, field, None).unwrap()
|
||||
}
|
||||
|
||||
pub fn insert_number_cell(num: i64, field: &Field) -> Cell {
|
||||
apply_cell_data_changeset(num.to_string(), None, field, None).unwrap()
|
||||
apply_cell_changeset(num.to_string(), None, field, None).unwrap()
|
||||
}
|
||||
|
||||
pub fn insert_url_cell(url: String, field: &Field) -> Cell {
|
||||
@ -212,7 +212,7 @@ pub fn insert_url_cell(url: String, field: &Field) -> Cell {
|
||||
_ => url,
|
||||
};
|
||||
|
||||
apply_cell_data_changeset(url, None, field, None).unwrap()
|
||||
apply_cell_changeset(url, None, field, None).unwrap()
|
||||
}
|
||||
|
||||
pub fn insert_checkbox_cell(is_check: bool, field: &Field) -> Cell {
|
||||
@ -221,7 +221,7 @@ pub fn insert_checkbox_cell(is_check: bool, field: &Field) -> Cell {
|
||||
} else {
|
||||
UNCHECK.to_string()
|
||||
};
|
||||
apply_cell_data_changeset(s, None, field, None).unwrap()
|
||||
apply_cell_changeset(s, None, field, None).unwrap()
|
||||
}
|
||||
|
||||
pub fn insert_date_cell(timestamp: i64, field: &Field) -> Cell {
|
||||
@ -232,19 +232,19 @@ pub fn insert_date_cell(timestamp: i64, field: &Field) -> Cell {
|
||||
timezone_id: None,
|
||||
})
|
||||
.unwrap();
|
||||
apply_cell_data_changeset(cell_data, None, field, None).unwrap()
|
||||
apply_cell_changeset(cell_data, None, field, None).unwrap()
|
||||
}
|
||||
|
||||
pub fn insert_select_option_cell(option_ids: Vec<String>, field: &Field) -> Cell {
|
||||
let changeset =
|
||||
SelectOptionCellChangeset::from_insert_options(option_ids).to_cell_changeset_str();
|
||||
apply_cell_data_changeset(changeset, None, field, None).unwrap()
|
||||
apply_cell_changeset(changeset, None, field, None).unwrap()
|
||||
}
|
||||
|
||||
pub fn delete_select_option_cell(option_ids: Vec<String>, field: &Field) -> Cell {
|
||||
let changeset =
|
||||
SelectOptionCellChangeset::from_delete_options(option_ids).to_cell_changeset_str();
|
||||
apply_cell_data_changeset(changeset, None, field, None).unwrap()
|
||||
apply_cell_changeset(changeset, None, field, None).unwrap()
|
||||
}
|
||||
|
||||
/// Deserialize the String into cell specific data type.
|
||||
|
@ -6,7 +6,7 @@ use bytes::Bytes;
|
||||
use collab_database::database::{gen_row_id, timestamp, Database as InnerDatabase};
|
||||
use collab_database::fields::{Field, TypeOptionData};
|
||||
use collab_database::rows::{Cell, Cells, Row, RowCell, RowId};
|
||||
use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting, RowOrder};
|
||||
use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting};
|
||||
use parking_lot::Mutex;
|
||||
use tokio::sync::{broadcast, RwLock};
|
||||
|
||||
@ -23,14 +23,11 @@ use crate::entities::{
|
||||
};
|
||||
use crate::notification::{send_notification, DatabaseNotification};
|
||||
use crate::services::cell::{
|
||||
apply_cell_data_changeset, get_type_cell_protobuf, AnyTypeCache, CellBuilder, CellCache,
|
||||
apply_cell_changeset, get_type_cell_protobuf, AnyTypeCache, CellBuilder, CellCache,
|
||||
ToCellChangeset,
|
||||
};
|
||||
use crate::services::database::util::database_view_setting_pb_from_view;
|
||||
use crate::services::database::{DatabaseRowEvent, InsertedRow, UpdatedRow};
|
||||
use crate::services::database_view::{
|
||||
DatabaseViewChanged, DatabaseViewData, DatabaseViews, RowEventSender,
|
||||
};
|
||||
use crate::services::database_view::{DatabaseViewChanged, DatabaseViewData, DatabaseViews};
|
||||
use crate::services::field::{
|
||||
default_type_option_data_for_type, default_type_option_data_from_type,
|
||||
select_type_option_from_field, transform_type_option, type_option_data_from_pb_or_default,
|
||||
@ -46,7 +43,6 @@ pub struct DatabaseEditor {
|
||||
database: MutexDatabase,
|
||||
pub cell_cache: CellCache,
|
||||
database_views: Arc<DatabaseViews>,
|
||||
row_event_tx: RowEventSender,
|
||||
}
|
||||
|
||||
impl DatabaseEditor {
|
||||
@ -55,27 +51,18 @@ impl DatabaseEditor {
|
||||
task_scheduler: Arc<RwLock<TaskDispatcher>>,
|
||||
) -> FlowyResult<Self> {
|
||||
let cell_cache = AnyTypeCache::<u64>::new();
|
||||
let (row_event_tx, row_event_rx) = broadcast::channel(100);
|
||||
let database_view_data = Arc::new(DatabaseViewDataImpl {
|
||||
database: database.clone(),
|
||||
task_scheduler: task_scheduler.clone(),
|
||||
cell_cache: cell_cache.clone(),
|
||||
});
|
||||
|
||||
let database_views = Arc::new(
|
||||
DatabaseViews::new(
|
||||
database.clone(),
|
||||
cell_cache.clone(),
|
||||
database_view_data,
|
||||
row_event_rx,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
let database_views =
|
||||
Arc::new(DatabaseViews::new(database.clone(), cell_cache.clone(), database_view_data).await?);
|
||||
Ok(Self {
|
||||
database,
|
||||
cell_cache,
|
||||
database_views,
|
||||
row_event_tx,
|
||||
})
|
||||
}
|
||||
|
||||
@ -295,7 +282,14 @@ impl DatabaseEditor {
|
||||
// self.database.lock().views.update_view(view_id, |view| {
|
||||
// view.move_row_order(from as u32, to as u32);
|
||||
// });
|
||||
// self.row_event_tx.send(DatabaseRowEvent::Move { from: _from, to: _to})
|
||||
// let changeset = RowsChangesetPB::from_move(
|
||||
// view_id.to_string(),
|
||||
// vec![from.into_inner()],
|
||||
// vec![to.into()],
|
||||
// );
|
||||
// send_notification(&self.view_id, DatabaseNotification::DidUpdateViewRows)
|
||||
// .payload(changeset)
|
||||
// .send();
|
||||
}
|
||||
|
||||
pub async fn create_row(&self, params: CreateRowParams) -> FlowyResult<Option<Row>> {
|
||||
@ -319,14 +313,6 @@ impl DatabaseEditor {
|
||||
);
|
||||
|
||||
if let Some((index, row_order)) = result {
|
||||
let _ = self
|
||||
.row_event_tx
|
||||
.send(DatabaseRowEvent::InsertRow(InsertedRow {
|
||||
row: row_order.clone(),
|
||||
index: Some(index as i32),
|
||||
is_new: true,
|
||||
}));
|
||||
|
||||
let row = self.database.lock().get_row(&row_order.id);
|
||||
if let Some(row) = row {
|
||||
for view in self.database_views.editors().await {
|
||||
@ -423,10 +409,6 @@ impl DatabaseEditor {
|
||||
let row = self.database.lock().remove_row(row_id);
|
||||
if let Some(row) = row {
|
||||
tracing::trace!("Did delete row:{:?}", row);
|
||||
let _ = self
|
||||
.row_event_tx
|
||||
.send(DatabaseRowEvent::DeleteRow(row.id.clone()));
|
||||
|
||||
for view in self.database_views.editors().await {
|
||||
view.v_did_delete_row(&row).await;
|
||||
}
|
||||
@ -481,15 +463,18 @@ impl DatabaseEditor {
|
||||
}?;
|
||||
(
|
||||
field,
|
||||
database.get_cell(field_id, &row_id).map(|cell| cell.cell),
|
||||
database
|
||||
.get_cell(field_id, &row_id)
|
||||
.map(|row_cell| row_cell.cell),
|
||||
)
|
||||
};
|
||||
let cell_changeset = cell_changeset.to_cell_changeset_str();
|
||||
let new_cell =
|
||||
apply_cell_data_changeset(cell_changeset, cell, &field, Some(self.cell_cache.clone()))?;
|
||||
apply_cell_changeset(cell_changeset, cell, &field, Some(self.cell_cache.clone()))?;
|
||||
self.update_cell(view_id, row_id, field_id, new_cell).await
|
||||
}
|
||||
|
||||
/// Update a cell in the database.
|
||||
/// This will notify all views that the cell has been updated.
|
||||
pub async fn update_cell(
|
||||
&self,
|
||||
view_id: &str,
|
||||
@ -497,6 +482,7 @@ impl DatabaseEditor {
|
||||
field_id: &str,
|
||||
new_cell: Cell,
|
||||
) -> FlowyResult<()> {
|
||||
// Get the old row before updating the cell. It would be better to get the old cell
|
||||
let old_row = { self.database.lock().get_row(&row_id) };
|
||||
self.database.lock().update_row(&row_id, |row_update| {
|
||||
row_update.update_cells(|cell_update| {
|
||||
@ -506,14 +492,8 @@ impl DatabaseEditor {
|
||||
|
||||
let option_row = self.database.lock().get_row(&row_id);
|
||||
if let Some(new_row) = option_row {
|
||||
let _ = self
|
||||
.row_event_tx
|
||||
.send(DatabaseRowEvent::UpdateRow(UpdatedRow {
|
||||
row: RowOrder::from(&new_row),
|
||||
field_ids: vec![field_id.to_string()],
|
||||
}));
|
||||
for view in self.database_views.editors().await {
|
||||
view.v_did_update_row(&old_row, &new_row).await;
|
||||
view.v_did_update_row(&old_row, &new_row, field_id).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ use std::sync::Arc;
|
||||
use collab_database::database::{gen_database_filter_id, gen_database_sort_id};
|
||||
use collab_database::fields::Field;
|
||||
use collab_database::rows::{Cells, Row, RowCell, RowId};
|
||||
use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting};
|
||||
use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting, RowOrder};
|
||||
use tokio::sync::{broadcast, RwLock};
|
||||
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
@ -20,7 +20,7 @@ use crate::entities::{
|
||||
};
|
||||
use crate::notification::{send_notification, DatabaseNotification};
|
||||
use crate::services::cell::CellCache;
|
||||
use crate::services::database::{database_view_setting_pb_from_view, DatabaseRowEvent};
|
||||
use crate::services::database::{database_view_setting_pb_from_view, DatabaseRowEvent, UpdatedRow};
|
||||
use crate::services::database_view::view_filter::make_filter_controller;
|
||||
use crate::services::database_view::view_group::{
|
||||
get_cell_for_row, get_cells_for_field, new_group_controller, new_group_controller_with_field,
|
||||
@ -55,6 +55,7 @@ pub trait DatabaseViewData: Send + Sync + 'static {
|
||||
/// Returns the `index` and `RowRevision` with row_id
|
||||
fn get_row(&self, view_id: &str, row_id: &RowId) -> Fut<Option<(usize, Arc<Row>)>>;
|
||||
|
||||
/// Returns all the rows in the view
|
||||
fn get_rows(&self, view_id: &str) -> Fut<Vec<Arc<Row>>>;
|
||||
|
||||
fn get_cells_for_field(&self, view_id: &str, field_id: &str) -> Fut<Vec<Arc<RowCell>>>;
|
||||
@ -180,7 +181,12 @@ impl DatabaseViewEditor {
|
||||
pub async fn v_did_create_row(&self, row: &Row, group_id: &Option<String>, index: usize) {
|
||||
// Send the group notification if the current view has groups
|
||||
match group_id.as_ref() {
|
||||
None => {},
|
||||
None => {
|
||||
let changeset = RowsChangesetPB::from_insert(self.view_id.clone(), vec![row.into()]);
|
||||
send_notification(&self.view_id, DatabaseNotification::DidUpdateViewRows)
|
||||
.payload(changeset)
|
||||
.send();
|
||||
},
|
||||
Some(group_id) => {
|
||||
self
|
||||
.group_controller
|
||||
@ -213,9 +219,17 @@ impl DatabaseViewEditor {
|
||||
notify_did_update_group_rows(changeset).await;
|
||||
}
|
||||
}
|
||||
let changeset =
|
||||
RowsChangesetPB::from_delete(self.view_id.clone(), vec![row.id.clone().into_inner()]);
|
||||
send_notification(&self.view_id, DatabaseNotification::DidUpdateViewRows)
|
||||
.payload(changeset)
|
||||
.send();
|
||||
}
|
||||
|
||||
pub async fn v_did_update_row(&self, old_row: &Option<Row>, row: &Row) {
|
||||
/// Notify the view that the row has been updated. If the view has groups,
|
||||
/// send the group notification with [GroupRowsNotificationPB]. Otherwise,
|
||||
/// send the view notification with [RowsChangesetPB]
|
||||
pub async fn v_did_update_row(&self, old_row: &Option<Row>, row: &Row, field_id: &str) {
|
||||
let result = self
|
||||
.mut_group_controller(|group_controller, field| {
|
||||
Ok(group_controller.did_update_group_row(old_row, row, &field))
|
||||
@ -244,20 +258,35 @@ impl DatabaseViewEditor {
|
||||
for changeset in result.row_changesets {
|
||||
notify_did_update_group_rows(changeset).await;
|
||||
}
|
||||
} else {
|
||||
let update_row = UpdatedRow {
|
||||
row: RowOrder::from(row),
|
||||
field_ids: vec![field_id.to_string()],
|
||||
};
|
||||
let changeset = RowsChangesetPB::from_update(self.view_id.clone(), vec![update_row.into()]);
|
||||
send_notification(&self.view_id, DatabaseNotification::DidUpdateViewRows)
|
||||
.payload(changeset)
|
||||
.send();
|
||||
}
|
||||
|
||||
let filter_controller = self.filter_controller.clone();
|
||||
let sort_controller = self.sort_controller.clone();
|
||||
// Each row update will trigger a filter and sort operation. We don't want
|
||||
// to block the main thread, so we spawn a new task to do the work.
|
||||
let row_id = row.id.clone();
|
||||
let weak_filter_controller = Arc::downgrade(&self.filter_controller);
|
||||
let weak_sort_controller = Arc::downgrade(&self.sort_controller);
|
||||
tokio::spawn(async move {
|
||||
filter_controller
|
||||
.did_receive_row_changed(row_id.clone())
|
||||
.await;
|
||||
sort_controller
|
||||
.read()
|
||||
.await
|
||||
.did_receive_row_changed(row_id)
|
||||
.await;
|
||||
if let Some(filter_controller) = weak_filter_controller.upgrade() {
|
||||
filter_controller
|
||||
.did_receive_row_changed(row_id.clone())
|
||||
.await;
|
||||
}
|
||||
if let Some(sort_controller) = weak_sort_controller.upgrade() {
|
||||
sort_controller
|
||||
.read()
|
||||
.await
|
||||
.did_receive_row_changed(row_id)
|
||||
.await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -513,7 +542,7 @@ impl DatabaseViewEditor {
|
||||
}
|
||||
|
||||
/// Returns the current calendar settings
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
pub async fn v_get_layout_settings(&self, layout_ty: &DatabaseLayout) -> LayoutSettingParams {
|
||||
let mut layout_setting = LayoutSettingParams::default();
|
||||
match layout_ty {
|
||||
@ -751,7 +780,7 @@ impl DatabaseViewEditor {
|
||||
Some(events)
|
||||
}
|
||||
|
||||
pub async fn handle_block_event(&self, event: Cow<'_, DatabaseRowEvent>) {
|
||||
pub async fn handle_row_event(&self, event: Cow<'_, DatabaseRowEvent>) {
|
||||
let changeset = match event.into_owned() {
|
||||
DatabaseRowEvent::InsertRow(row) => {
|
||||
RowsChangesetPB::from_insert(self.view_id.clone(), vec![row.into()])
|
||||
|
@ -1,4 +1,3 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -31,10 +30,8 @@ impl DatabaseViews {
|
||||
database: MutexDatabase,
|
||||
cell_cache: CellCache,
|
||||
database_view_data: Arc<dyn DatabaseViewData>,
|
||||
row_event_rx: RowEventReceiver,
|
||||
) -> FlowyResult<Self> {
|
||||
let editor_map = Arc::new(RwLock::new(HashMap::default()));
|
||||
listen_on_database_row_event(row_event_rx, editor_map.clone());
|
||||
Ok(Self {
|
||||
database,
|
||||
database_view_data,
|
||||
@ -126,26 +123,6 @@ impl DatabaseViews {
|
||||
}
|
||||
}
|
||||
|
||||
fn listen_on_database_row_event(
|
||||
mut row_event_rx: broadcast::Receiver<DatabaseRowEvent>,
|
||||
view_editors: Arc<RwLock<HashMap<String, Arc<DatabaseViewEditor>>>>,
|
||||
) {
|
||||
tokio::spawn(async move {
|
||||
while let Ok(event) = row_event_rx.recv().await {
|
||||
let read_guard = view_editors.read().await;
|
||||
let view_editors = read_guard.values();
|
||||
let event = if view_editors.len() == 1 {
|
||||
Cow::Owned(event)
|
||||
} else {
|
||||
Cow::Borrowed(&event)
|
||||
};
|
||||
for view_editor in view_editors {
|
||||
view_editor.handle_block_event(event.clone()).await;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn gen_handler_id() -> String {
|
||||
nanoid!(10)
|
||||
}
|
||||
|
@ -7,10 +7,15 @@ use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref CURRENCY_SYMBOL: Vec<String> = NumberFormat::iter()
|
||||
pub static ref CURRENCY_SYMBOL: Vec<String> = sorted_symbol();
|
||||
}
|
||||
|
||||
fn sorted_symbol() -> Vec<String> {
|
||||
let mut symbols = NumberFormat::iter()
|
||||
.map(|format| format.symbol())
|
||||
.collect::<Vec<String>>();
|
||||
pub static ref STRIP_SYMBOL: Vec<String> = vec![",".to_owned(), ".".to_owned()];
|
||||
symbols.sort_by(|a, b| b.len().cmp(&a.len()));
|
||||
symbols
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, Serialize, Deserialize)]
|
||||
|
@ -47,13 +47,13 @@ mod tests {
|
||||
};
|
||||
|
||||
for (num_str, visible) in [("123", true), ("1234", false), ("", false)] {
|
||||
let data = NumberCellFormat::from_format_str(num_str, true, &NumberFormat::Num).unwrap();
|
||||
let data = NumberCellFormat::from_format_str(num_str, &NumberFormat::Num).unwrap_or_default();
|
||||
assert_eq!(number_filter.is_visible(&data), visible);
|
||||
}
|
||||
|
||||
let format = NumberFormat::USD;
|
||||
for (num_str, visible) in [("$123", true), ("1234", false), ("", false)] {
|
||||
let data = NumberCellFormat::from_format_str(num_str, true, &format).unwrap();
|
||||
let data = NumberCellFormat::from_format_str(num_str, &format).unwrap();
|
||||
assert_eq!(number_filter.is_visible(&data), visible);
|
||||
}
|
||||
}
|
||||
@ -64,7 +64,7 @@ mod tests {
|
||||
content: "12".to_owned(),
|
||||
};
|
||||
for (num_str, visible) in [("123", true), ("10", false), ("30", true), ("", false)] {
|
||||
let data = NumberCellFormat::from_format_str(num_str, true, &NumberFormat::Num).unwrap();
|
||||
let data = NumberCellFormat::from_format_str(num_str, &NumberFormat::Num).unwrap_or_default();
|
||||
assert_eq!(number_filter.is_visible(&data), visible);
|
||||
}
|
||||
}
|
||||
@ -76,7 +76,7 @@ mod tests {
|
||||
content: "100".to_owned(),
|
||||
};
|
||||
for (num_str, visible) in [("12", true), ("1234", false), ("30", true), ("", false)] {
|
||||
let data = NumberCellFormat::from_format_str(num_str, true, &NumberFormat::Num).unwrap();
|
||||
let data = NumberCellFormat::from_format_str(num_str, &NumberFormat::Num).unwrap_or_default();
|
||||
assert_eq!(number_filter.is_visible(&data), visible);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use collab_database::fields::Field;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::cell::CellDataDecoder;
|
||||
use crate::services::field::{strip_currency_symbol, NumberFormat, NumberTypeOption};
|
||||
use crate::services::field::{FieldBuilder, NumberCellData};
|
||||
use crate::services::field::{NumberFormat, NumberTypeOption};
|
||||
|
||||
/// Testing when the input is not a number.
|
||||
#[test]
|
||||
fn number_type_option_invalid_input_test() {
|
||||
fn number_type_option_input_test() {
|
||||
let type_option = NumberTypeOption::default();
|
||||
let field_type = FieldType::Number;
|
||||
let field = FieldBuilder::from_field_type(field_type.clone()).build();
|
||||
@ -20,492 +19,65 @@ mod tests {
|
||||
|
||||
// Input is letter
|
||||
assert_number(&type_option, "abc", "", &field_type, &field);
|
||||
|
||||
assert_number(&type_option, "-123", "-123", &field_type, &field);
|
||||
|
||||
assert_number(&type_option, "abc-123", "-123", &field_type, &field);
|
||||
|
||||
assert_number(&type_option, "+123", "123", &field_type, &field);
|
||||
|
||||
assert_number(&type_option, "0.2", "0.2", &field_type, &field);
|
||||
|
||||
assert_number(&type_option, "-0.2", "-0.2", &field_type, &field);
|
||||
assert_number(&type_option, "-$0.2", "0.2", &field_type, &field);
|
||||
}
|
||||
|
||||
/// Testing the strip_currency_symbol function. It should return the string without the input symbol.
|
||||
#[test]
|
||||
fn number_type_option_strip_symbol_test() {
|
||||
// Remove the $ symbol
|
||||
assert_eq!(strip_currency_symbol("$18,443"), "18,443".to_owned());
|
||||
// Remove the ¥ symbol
|
||||
assert_eq!(strip_currency_symbol("¥0.2"), "0.2".to_owned());
|
||||
}
|
||||
|
||||
/// Format the input number to the corresponding format string.
|
||||
#[test]
|
||||
fn number_type_option_format_number_test() {
|
||||
let mut type_option = NumberTypeOption::default();
|
||||
fn dollar_type_option_test() {
|
||||
let field_type = FieldType::Number;
|
||||
let field = FieldBuilder::from_field_type(field_type.clone()).build();
|
||||
let mut type_option = NumberTypeOption::new();
|
||||
type_option.format = NumberFormat::USD;
|
||||
let field = FieldBuilder::new(field_type.clone(), type_option.clone()).build();
|
||||
|
||||
for format in NumberFormat::iter() {
|
||||
type_option.format = format;
|
||||
match format {
|
||||
NumberFormat::Num => {
|
||||
assert_number(&type_option, "18443", "18443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::USD => {
|
||||
assert_number(&type_option, "18443", "$18,443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::CanadianDollar => {
|
||||
assert_number(&type_option, "18443", "CA$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::EUR => assert_number(&type_option, "18443", "€18.443", &field_type, &field),
|
||||
NumberFormat::Pound => assert_number(&type_option, "18443", "£18,443", &field_type, &field),
|
||||
|
||||
NumberFormat::Yen => {
|
||||
assert_number(&type_option, "18443", "¥18,443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Ruble => {
|
||||
assert_number(&type_option, "18443", "18.443RUB", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Rupee => assert_number(&type_option, "18443", "₹18,443", &field_type, &field),
|
||||
NumberFormat::Won => assert_number(&type_option, "18443", "₩18,443", &field_type, &field),
|
||||
|
||||
NumberFormat::Yuan => {
|
||||
assert_number(&type_option, "18443", "CN¥18,443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Real => {
|
||||
assert_number(&type_option, "18443", "R$18,443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Lira => {
|
||||
assert_number(&type_option, "18443", "TRY18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Rupiah => {
|
||||
assert_number(&type_option, "18443", "IDR18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Franc => {
|
||||
assert_number(&type_option, "18443", "CHF18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::HongKongDollar => {
|
||||
assert_number(&type_option, "18443", "HZ$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::NewZealandDollar => {
|
||||
assert_number(&type_option, "18443", "NZ$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Krona => {
|
||||
assert_number(&type_option, "18443", "18 443SEK", &field_type, &field)
|
||||
},
|
||||
NumberFormat::NorwegianKrone => {
|
||||
assert_number(&type_option, "18443", "18,443NOK", &field_type, &field)
|
||||
},
|
||||
NumberFormat::MexicanPeso => {
|
||||
assert_number(&type_option, "18443", "MX$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Rand => {
|
||||
assert_number(&type_option, "18443", "ZAR18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::NewTaiwanDollar => {
|
||||
assert_number(&type_option, "18443", "NT$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::DanishKrone => {
|
||||
assert_number(&type_option, "18443", "18.443DKK", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Baht => {
|
||||
assert_number(&type_option, "18443", "THB18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Forint => {
|
||||
assert_number(&type_option, "18443", "18 443HUF", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Koruna => {
|
||||
assert_number(&type_option, "18443", "18 443CZK", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Shekel => {
|
||||
assert_number(&type_option, "18443", "18 443Kč", &field_type, &field)
|
||||
},
|
||||
NumberFormat::ChileanPeso => {
|
||||
assert_number(&type_option, "18443", "CLP18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::PhilippinePeso => {
|
||||
assert_number(&type_option, "18443", "₱18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Dirham => {
|
||||
assert_number(&type_option, "18443", "18,443AED", &field_type, &field)
|
||||
},
|
||||
NumberFormat::ColombianPeso => {
|
||||
assert_number(&type_option, "18443", "COP18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Riyal => {
|
||||
assert_number(&type_option, "18443", "SAR18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Ringgit => {
|
||||
assert_number(&type_option, "18443", "MYR18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Leu => assert_number(&type_option, "18443", "18.443RON", &field_type, &field),
|
||||
NumberFormat::ArgentinePeso => {
|
||||
assert_number(&type_option, "18443", "ARS18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::UruguayanPeso => {
|
||||
assert_number(&type_option, "18443", "UYU18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Percent => {
|
||||
assert_number(&type_option, "18443", "18,443%", &field_type, &field)
|
||||
},
|
||||
}
|
||||
}
|
||||
assert_number(&type_option, "", "", &field_type, &field);
|
||||
assert_number(&type_option, "abc", "", &field_type, &field);
|
||||
assert_number(&type_option, "-123", "-$123", &field_type, &field);
|
||||
assert_number(&type_option, "+123", "$123", &field_type, &field);
|
||||
assert_number(&type_option, "0.2", "$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "-0.2", "-$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "-$0.2", "-$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "-€0.2", "-$0.2", &field_type, &field);
|
||||
}
|
||||
|
||||
/// Format the input String to the corresponding format string.
|
||||
#[test]
|
||||
fn number_type_option_format_str_test() {
|
||||
let mut type_option = NumberTypeOption::default();
|
||||
fn dollar_type_option_test2() {
|
||||
let field_type = FieldType::Number;
|
||||
let field = FieldBuilder::from_field_type(field_type.clone()).build();
|
||||
let mut type_option = NumberTypeOption::new();
|
||||
type_option.format = NumberFormat::USD;
|
||||
let field = FieldBuilder::new(field_type.clone(), type_option.clone()).build();
|
||||
|
||||
for format in NumberFormat::iter() {
|
||||
type_option.format = format;
|
||||
match format {
|
||||
NumberFormat::Num => {
|
||||
assert_number(&type_option, "18443", "18443", &field_type, &field);
|
||||
assert_number(&type_option, "0.2", "0.2", &field_type, &field);
|
||||
assert_number(&type_option, "", "", &field_type, &field);
|
||||
assert_number(&type_option, "abc", "", &field_type, &field);
|
||||
},
|
||||
NumberFormat::USD => {
|
||||
assert_number(&type_option, "$18,44", "$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "$0.2", "$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "$1844", "$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "$1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::CanadianDollar => {
|
||||
assert_number(&type_option, "CA$18,44", "CA$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "CA$0.2", "CA$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "CA$1844", "CA$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "CA$1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::EUR => {
|
||||
assert_number(&type_option, "€18.44", "€18,44", &field_type, &field);
|
||||
assert_number(&type_option, "€0.5", "€0,5", &field_type, &field);
|
||||
assert_number(&type_option, "€1844", "€1.844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "€1.844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Pound => {
|
||||
assert_number(&type_option, "£18,44", "£1,844", &field_type, &field);
|
||||
assert_number(&type_option, "£0.2", "£0.2", &field_type, &field);
|
||||
assert_number(&type_option, "£1844", "£1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "£1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Yen => {
|
||||
assert_number(&type_option, "¥18,44", "¥1,844", &field_type, &field);
|
||||
assert_number(&type_option, "¥0.2", "¥0.2", &field_type, &field);
|
||||
assert_number(&type_option, "¥1844", "¥1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "¥1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Ruble => {
|
||||
assert_number(&type_option, "RUB18.44", "18,44RUB", &field_type, &field);
|
||||
assert_number(&type_option, "0.5", "0,5RUB", &field_type, &field);
|
||||
assert_number(&type_option, "RUB1844", "1.844RUB", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1.844RUB", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Rupee => {
|
||||
assert_number(&type_option, "₹18,44", "₹1,844", &field_type, &field);
|
||||
assert_number(&type_option, "₹0.2", "₹0.2", &field_type, &field);
|
||||
assert_number(&type_option, "₹1844", "₹1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "₹1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Won => {
|
||||
assert_number(&type_option, "₩18,44", "₩1,844", &field_type, &field);
|
||||
assert_number(&type_option, "₩0.3", "₩0", &field_type, &field);
|
||||
assert_number(&type_option, "₩1844", "₩1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "₩1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Yuan => {
|
||||
assert_number(&type_option, "CN¥18,44", "CN¥1,844", &field_type, &field);
|
||||
assert_number(&type_option, "CN¥0.2", "CN¥0.2", &field_type, &field);
|
||||
assert_number(&type_option, "CN¥1844", "CN¥1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "CN¥1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Real => {
|
||||
assert_number(&type_option, "R$18,44", "R$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "R$0.2", "R$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "R$1844", "R$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "R$1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Lira => {
|
||||
assert_number(&type_option, "TRY18.44", "TRY18,44", &field_type, &field);
|
||||
assert_number(&type_option, "TRY0.5", "TRY0,5", &field_type, &field);
|
||||
assert_number(&type_option, "TRY1844", "TRY1.844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "TRY1.844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Rupiah => {
|
||||
assert_number(&type_option, "IDR18,44", "IDR1,844", &field_type, &field);
|
||||
assert_number(&type_option, "IDR0.2", "IDR0.2", &field_type, &field);
|
||||
assert_number(&type_option, "IDR1844", "IDR1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "IDR1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Franc => {
|
||||
assert_number(&type_option, "CHF18,44", "CHF1,844", &field_type, &field);
|
||||
assert_number(&type_option, "CHF0.2", "CHF0.2", &field_type, &field);
|
||||
assert_number(&type_option, "CHF1844", "CHF1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "CHF1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::HongKongDollar => {
|
||||
assert_number(&type_option, "HZ$18,44", "HZ$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "HZ$0.2", "HZ$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "HZ$1844", "HZ$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "HZ$1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::NewZealandDollar => {
|
||||
assert_number(&type_option, "NZ$18,44", "NZ$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "NZ$0.2", "NZ$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "NZ$1844", "NZ$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "NZ$1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Krona => {
|
||||
assert_number(&type_option, "SEK18,44", "18,44SEK", &field_type, &field);
|
||||
assert_number(&type_option, "SEK0.2", "0,2SEK", &field_type, &field);
|
||||
assert_number(&type_option, "SEK1844", "1 844SEK", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1 844SEK", &field_type, &field);
|
||||
},
|
||||
NumberFormat::NorwegianKrone => {
|
||||
assert_number(&type_option, "NOK18,44", "1,844NOK", &field_type, &field);
|
||||
assert_number(&type_option, "NOK0.2", "0.2NOK", &field_type, &field);
|
||||
assert_number(&type_option, "NOK1844", "1,844NOK", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1,844NOK", &field_type, &field);
|
||||
},
|
||||
NumberFormat::MexicanPeso => {
|
||||
assert_number(&type_option, "MX$18,44", "MX$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "MX$0.2", "MX$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "MX$1844", "MX$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "MX$1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Rand => {
|
||||
assert_number(&type_option, "ZAR18,44", "ZAR1,844", &field_type, &field);
|
||||
assert_number(&type_option, "ZAR0.2", "ZAR0.2", &field_type, &field);
|
||||
assert_number(&type_option, "ZAR1844", "ZAR1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "ZAR1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::NewTaiwanDollar => {
|
||||
assert_number(&type_option, "NT$18,44", "NT$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "NT$0.2", "NT$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "NT$1844", "NT$1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "NT$1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::DanishKrone => {
|
||||
assert_number(&type_option, "DKK18.44", "18,44DKK", &field_type, &field);
|
||||
assert_number(&type_option, "DKK0.5", "0,5DKK", &field_type, &field);
|
||||
assert_number(&type_option, "DKK1844", "1.844DKK", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1.844DKK", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Baht => {
|
||||
assert_number(&type_option, "THB18,44", "THB1,844", &field_type, &field);
|
||||
assert_number(&type_option, "THB0.2", "THB0.2", &field_type, &field);
|
||||
assert_number(&type_option, "THB1844", "THB1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "THB1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Forint => {
|
||||
assert_number(&type_option, "HUF18,44", "18HUF", &field_type, &field);
|
||||
assert_number(&type_option, "HUF0.3", "0HUF", &field_type, &field);
|
||||
assert_number(&type_option, "HUF1844", "1 844HUF", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1 844HUF", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Koruna => {
|
||||
assert_number(&type_option, "CZK18,44", "18,44CZK", &field_type, &field);
|
||||
assert_number(&type_option, "CZK0.2", "0,2CZK", &field_type, &field);
|
||||
assert_number(&type_option, "CZK1844", "1 844CZK", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1 844CZK", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Shekel => {
|
||||
assert_number(&type_option, "Kč18,44", "18,44Kč", &field_type, &field);
|
||||
assert_number(&type_option, "Kč0.2", "0,2Kč", &field_type, &field);
|
||||
assert_number(&type_option, "Kč1844", "1 844Kč", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1 844Kč", &field_type, &field);
|
||||
},
|
||||
NumberFormat::ChileanPeso => {
|
||||
assert_number(&type_option, "CLP18.44", "CLP18", &field_type, &field);
|
||||
assert_number(&type_option, "0.5", "CLP0", &field_type, &field);
|
||||
assert_number(&type_option, "CLP1844", "CLP1.844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "CLP1.844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::PhilippinePeso => {
|
||||
assert_number(&type_option, "₱18,44", "₱1,844", &field_type, &field);
|
||||
assert_number(&type_option, "₱0.2", "₱0.2", &field_type, &field);
|
||||
assert_number(&type_option, "₱1844", "₱1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "₱1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Dirham => {
|
||||
assert_number(&type_option, "AED18,44", "1,844AED", &field_type, &field);
|
||||
assert_number(&type_option, "AED0.2", "0.2AED", &field_type, &field);
|
||||
assert_number(&type_option, "AED1844", "1,844AED", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1,844AED", &field_type, &field);
|
||||
},
|
||||
NumberFormat::ColombianPeso => {
|
||||
assert_number(&type_option, "COP18.44", "COP18,44", &field_type, &field);
|
||||
assert_number(&type_option, "0.5", "COP0,5", &field_type, &field);
|
||||
assert_number(&type_option, "COP1844", "COP1.844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "COP1.844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Riyal => {
|
||||
assert_number(&type_option, "SAR18,44", "SAR1,844", &field_type, &field);
|
||||
assert_number(&type_option, "SAR0.2", "SAR0.2", &field_type, &field);
|
||||
assert_number(&type_option, "SAR1844", "SAR1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "SAR1,844", &field_type, &field);
|
||||
},
|
||||
|
||||
NumberFormat::Ringgit => {
|
||||
assert_number(&type_option, "MYR18,44", "MYR1,844", &field_type, &field);
|
||||
assert_number(&type_option, "MYR0.2", "MYR0.2", &field_type, &field);
|
||||
assert_number(&type_option, "MYR1844", "MYR1,844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "MYR1,844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Leu => {
|
||||
assert_number(&type_option, "RON18.44", "18,44RON", &field_type, &field);
|
||||
assert_number(&type_option, "0.5", "0,5RON", &field_type, &field);
|
||||
assert_number(&type_option, "RON1844", "1.844RON", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "1.844RON", &field_type, &field);
|
||||
},
|
||||
NumberFormat::ArgentinePeso => {
|
||||
assert_number(&type_option, "ARS18.44", "ARS18,44", &field_type, &field);
|
||||
assert_number(&type_option, "0.5", "ARS0,5", &field_type, &field);
|
||||
assert_number(&type_option, "ARS1844", "ARS1.844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "ARS1.844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::UruguayanPeso => {
|
||||
assert_number(&type_option, "UYU18.44", "UYU18,44", &field_type, &field);
|
||||
assert_number(&type_option, "0.5", "UYU0,5", &field_type, &field);
|
||||
assert_number(&type_option, "UYU1844", "UYU1.844", &field_type, &field);
|
||||
assert_number(&type_option, "1844", "UYU1.844", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Percent => {
|
||||
assert_number(&type_option, "1", "1%", &field_type, &field);
|
||||
assert_number(&type_option, "10.1", "10.1%", &field_type, &field);
|
||||
assert_number(&type_option, "100", "100%", &field_type, &field);
|
||||
},
|
||||
}
|
||||
}
|
||||
assert_number(
|
||||
&type_option,
|
||||
"99999999999",
|
||||
"$99,999,999,999",
|
||||
&field_type,
|
||||
&field,
|
||||
);
|
||||
assert_number(
|
||||
&type_option,
|
||||
"$99,999,999,999",
|
||||
"$99,999,999,999",
|
||||
&field_type,
|
||||
&field,
|
||||
);
|
||||
}
|
||||
|
||||
/// Carry out the sign positive to input number
|
||||
#[test]
|
||||
fn number_description_sign_test() {
|
||||
let mut type_option = NumberTypeOption {
|
||||
sign_positive: false,
|
||||
..Default::default()
|
||||
};
|
||||
fn other_symbol_to_dollar_type_option_test() {
|
||||
let field_type = FieldType::Number;
|
||||
let field = FieldBuilder::from_field_type(field_type.clone()).build();
|
||||
let mut type_option = NumberTypeOption::new();
|
||||
type_option.format = NumberFormat::USD;
|
||||
let field = FieldBuilder::new(field_type.clone(), type_option.clone()).build();
|
||||
|
||||
for format in NumberFormat::iter() {
|
||||
type_option.format = format;
|
||||
match format {
|
||||
NumberFormat::Num => {
|
||||
assert_number(&type_option, "18443", "18443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::USD => {
|
||||
assert_number(&type_option, "18443", "-$18,443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::CanadianDollar => {
|
||||
assert_number(&type_option, "18443", "-CA$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::EUR => assert_number(&type_option, "18443", "-€18.443", &field_type, &field),
|
||||
NumberFormat::Pound => {
|
||||
assert_number(&type_option, "18443", "-£18,443", &field_type, &field)
|
||||
},
|
||||
|
||||
NumberFormat::Yen => {
|
||||
assert_number(&type_option, "18443", "-¥18,443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Ruble => {
|
||||
assert_number(&type_option, "18443", "-18.443RUB", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Rupee => {
|
||||
assert_number(&type_option, "18443", "-₹18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Won => assert_number(&type_option, "18443", "-₩18,443", &field_type, &field),
|
||||
|
||||
NumberFormat::Yuan => {
|
||||
assert_number(&type_option, "18443", "-CN¥18,443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Real => {
|
||||
assert_number(&type_option, "18443", "-R$18,443", &field_type, &field);
|
||||
},
|
||||
NumberFormat::Lira => {
|
||||
assert_number(&type_option, "18443", "-TRY18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Rupiah => {
|
||||
assert_number(&type_option, "18443", "-IDR18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Franc => {
|
||||
assert_number(&type_option, "18443", "-CHF18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::HongKongDollar => {
|
||||
assert_number(&type_option, "18443", "-HZ$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::NewZealandDollar => {
|
||||
assert_number(&type_option, "18443", "-NZ$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Krona => {
|
||||
assert_number(&type_option, "18443", "-18 443SEK", &field_type, &field)
|
||||
},
|
||||
NumberFormat::NorwegianKrone => {
|
||||
assert_number(&type_option, "18443", "-18,443NOK", &field_type, &field)
|
||||
},
|
||||
NumberFormat::MexicanPeso => {
|
||||
assert_number(&type_option, "18443", "-MX$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Rand => {
|
||||
assert_number(&type_option, "18443", "-ZAR18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::NewTaiwanDollar => {
|
||||
assert_number(&type_option, "18443", "-NT$18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::DanishKrone => {
|
||||
assert_number(&type_option, "18443", "-18.443DKK", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Baht => {
|
||||
assert_number(&type_option, "18443", "-THB18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Forint => {
|
||||
assert_number(&type_option, "18443", "-18 443HUF", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Koruna => {
|
||||
assert_number(&type_option, "18443", "-18 443CZK", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Shekel => {
|
||||
assert_number(&type_option, "18443", "-18 443Kč", &field_type, &field)
|
||||
},
|
||||
NumberFormat::ChileanPeso => {
|
||||
assert_number(&type_option, "18443", "-CLP18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::PhilippinePeso => {
|
||||
assert_number(&type_option, "18443", "-₱18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Dirham => {
|
||||
assert_number(&type_option, "18443", "-18,443AED", &field_type, &field)
|
||||
},
|
||||
NumberFormat::ColombianPeso => {
|
||||
assert_number(&type_option, "18443", "-COP18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Riyal => {
|
||||
assert_number(&type_option, "18443", "-SAR18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Ringgit => {
|
||||
assert_number(&type_option, "18443", "-MYR18,443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Leu => {
|
||||
assert_number(&type_option, "18443", "-18.443RON", &field_type, &field)
|
||||
},
|
||||
NumberFormat::ArgentinePeso => {
|
||||
assert_number(&type_option, "18443", "-ARS18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::UruguayanPeso => {
|
||||
assert_number(&type_option, "18443", "-UYU18.443", &field_type, &field)
|
||||
},
|
||||
NumberFormat::Percent => {
|
||||
assert_number(&type_option, "18443", "-18,443%", &field_type, &field)
|
||||
},
|
||||
}
|
||||
}
|
||||
assert_number(&type_option, "€0.2", "$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "-€0.2", "-$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "-CN¥0.2", "-$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "CN¥0.2", "$0.2", &field_type, &field);
|
||||
assert_number(&type_option, "0.2", "$0.2", &field_type, &field);
|
||||
}
|
||||
|
||||
fn assert_number(
|
||||
@ -513,14 +85,14 @@ mod tests {
|
||||
input_str: &str,
|
||||
expected_str: &str,
|
||||
field_type: &FieldType,
|
||||
field_rev: &Field,
|
||||
field: &Field,
|
||||
) {
|
||||
assert_eq!(
|
||||
type_option
|
||||
.decode_cell_str(
|
||||
&NumberCellData(input_str.to_owned()).into(),
|
||||
field_type,
|
||||
field_rev
|
||||
field
|
||||
)
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
|
@ -27,7 +27,6 @@ pub struct NumberTypeOption {
|
||||
pub format: NumberFormat,
|
||||
pub scale: u32,
|
||||
pub symbol: String,
|
||||
pub sign_positive: bool,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
@ -75,13 +74,11 @@ impl From<TypeOptionData> for NumberTypeOption {
|
||||
.unwrap_or_default();
|
||||
let scale = data.get_i64_value("scale").unwrap_or_default() as u32;
|
||||
let symbol = data.get_str_value("symbol").unwrap_or_default();
|
||||
let sign_positive = data.get_bool_value("sign_positive").unwrap_or_default();
|
||||
let name = data.get_str_value("name").unwrap_or_default();
|
||||
Self {
|
||||
format,
|
||||
scale,
|
||||
symbol,
|
||||
sign_positive,
|
||||
name,
|
||||
}
|
||||
}
|
||||
@ -92,7 +89,6 @@ impl From<NumberTypeOption> for TypeOptionData {
|
||||
TypeOptionDataBuilder::new()
|
||||
.insert_i64_value("format", data.format.value())
|
||||
.insert_i64_value("scale", data.scale as i64)
|
||||
.insert_bool_value("sign_positive", data.sign_positive)
|
||||
.insert_str_value("name", data.name)
|
||||
.insert_str_value("symbol", data.symbol)
|
||||
.build()
|
||||
@ -132,20 +128,23 @@ impl NumberTypeOption {
|
||||
Err(_) => Ok(NumberCellFormat::new()),
|
||||
}
|
||||
} else {
|
||||
let num = match EXTRACT_NUM_REGEX.captures(&num_cell_data.0) {
|
||||
let num_str = match EXTRACT_NUM_REGEX.captures(&num_cell_data.0) {
|
||||
Ok(Some(captures)) => captures
|
||||
.get(0)
|
||||
.map(|m| m.as_str().to_string())
|
||||
.unwrap_or_default(),
|
||||
_ => "".to_string(),
|
||||
};
|
||||
match Decimal::from_str(&num) {
|
||||
Ok(value, ..) => Ok(NumberCellFormat::from_decimal(value)),
|
||||
|
||||
match Decimal::from_str(&num_str) {
|
||||
Ok(decimal, ..) => {
|
||||
return Ok(NumberCellFormat::from_decimal(decimal));
|
||||
},
|
||||
Err(_) => Ok(NumberCellFormat::new()),
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => NumberCellFormat::from_format_str(&num_cell_data.0, self.sign_positive, &self.format),
|
||||
_ => NumberCellFormat::from_format_str(&num_cell_data.0, &self.format),
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,17 +154,6 @@ impl NumberTypeOption {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn strip_currency_symbol<T: ToString>(s: T) -> String {
|
||||
let mut s = s.to_string();
|
||||
for symbol in CURRENCY_SYMBOL.iter() {
|
||||
if s.starts_with(symbol) {
|
||||
s = s.strip_prefix(symbol).unwrap_or("").to_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
impl TypeOptionTransform for NumberTypeOption {}
|
||||
|
||||
impl CellDataDecoder for NumberTypeOption {
|
||||
@ -206,9 +194,11 @@ impl CellDataChangeset for NumberTypeOption {
|
||||
changeset: <Self as TypeOption>::CellChangeset,
|
||||
_cell: Option<Cell>,
|
||||
) -> FlowyResult<(Cell, <Self as TypeOption>::CellData)> {
|
||||
let number_cell_data = NumberCellData(changeset.trim().to_string());
|
||||
let num_str = changeset.trim().to_string();
|
||||
let number_cell_data = NumberCellData(num_str);
|
||||
let formatter = self.format_cell_data(&number_cell_data)?;
|
||||
|
||||
tracing::trace!("number: {:?}", number_cell_data);
|
||||
match self.format {
|
||||
NumberFormat::Num => Ok((
|
||||
NumberCellData(formatter.to_string()).into(),
|
||||
@ -245,9 +235,8 @@ impl TypeOptionCellDataCompare for NumberTypeOption {
|
||||
cell_data: &<Self as TypeOption>::CellData,
|
||||
other_cell_data: &<Self as TypeOption>::CellData,
|
||||
) -> Ordering {
|
||||
let left = NumberCellFormat::from_format_str(&cell_data.0, self.sign_positive, &self.format);
|
||||
let right =
|
||||
NumberCellFormat::from_format_str(&other_cell_data.0, self.sign_positive, &self.format);
|
||||
let left = NumberCellFormat::from_format_str(&cell_data.0, &self.format);
|
||||
let right = NumberCellFormat::from_format_str(&other_cell_data.0, &self.format);
|
||||
match (left, right) {
|
||||
(Ok(left), Ok(right)) => {
|
||||
return left.decimal().cmp(right.decimal());
|
||||
@ -266,7 +255,6 @@ impl std::default::Default for NumberTypeOption {
|
||||
format,
|
||||
scale: 0,
|
||||
symbol,
|
||||
sign_positive: true,
|
||||
name: "Number".to_string(),
|
||||
}
|
||||
}
|
||||
@ -274,5 +262,5 @@ impl std::default::Default for NumberTypeOption {
|
||||
|
||||
lazy_static! {
|
||||
static ref SCIENTIFIC_NOTATION_REGEX: Regex = Regex::new(r"([+-]?\d*\.?\d+)e([+-]?\d+)").unwrap();
|
||||
static ref EXTRACT_NUM_REGEX: Regex = Regex::new(r"-?\d+(\.\d+)?").unwrap();
|
||||
pub(crate) static ref EXTRACT_NUM_REGEX: Regex = Regex::new(r"-?\d+(\.\d+)?").unwrap();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::services::cell::{CellBytesCustomParser, CellProtobufBlobParser, DecodedCellData};
|
||||
use crate::services::field::number_currency::Currency;
|
||||
use crate::services::field::{strip_currency_symbol, NumberFormat, STRIP_SYMBOL};
|
||||
use crate::services::field::{NumberFormat, EXTRACT_NUM_REGEX};
|
||||
use bytes::Bytes;
|
||||
use flowy_error::FlowyResult;
|
||||
use rust_decimal::Decimal;
|
||||
@ -21,29 +21,28 @@ impl NumberCellFormat {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_format_str(s: &str, sign_positive: bool, format: &NumberFormat) -> FlowyResult<Self> {
|
||||
let mut num_str = strip_currency_symbol(s);
|
||||
let currency = format.currency();
|
||||
/// The num_str might contain currency symbol, e.g. $1,000.00
|
||||
pub fn from_format_str(num_str: &str, format: &NumberFormat) -> FlowyResult<Self> {
|
||||
if num_str.is_empty() {
|
||||
return Ok(Self::default());
|
||||
}
|
||||
// If the first char is not '-', then it is a sign.
|
||||
let sign_positive = match num_str.find("-") {
|
||||
None => true,
|
||||
Some(offset) => offset != 0,
|
||||
};
|
||||
|
||||
// Extract number from string.
|
||||
let num_str = extract_number(num_str);
|
||||
match Decimal::from_str(&num_str) {
|
||||
Ok(mut decimal) => {
|
||||
decimal.set_sign_positive(sign_positive);
|
||||
let money = Money::from_decimal(decimal, currency);
|
||||
let money = Money::from_decimal(decimal, format.currency());
|
||||
Ok(Self::from_money(money))
|
||||
},
|
||||
Err(_) => match Money::from_str(&num_str, currency) {
|
||||
Ok(money) => Ok(NumberCellFormat::from_money(money)),
|
||||
Err(_) => {
|
||||
num_str.retain(|c| !STRIP_SYMBOL.contains(&c.to_string()));
|
||||
if num_str.chars().all(char::is_numeric) {
|
||||
Self::from_format_str(&num_str, sign_positive, format)
|
||||
} else {
|
||||
// returns empty string if it can be formatted
|
||||
Ok(Self::default())
|
||||
}
|
||||
},
|
||||
Err(_) => match Money::from_str(&num_str, format.currency()) {
|
||||
Ok(money) => Ok(Self::from_money(money)),
|
||||
Err(_) => Ok(Self::default()),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -71,17 +70,14 @@ impl NumberCellFormat {
|
||||
}
|
||||
}
|
||||
|
||||
// impl FromStr for NumberCellData {
|
||||
// type Err = FlowyError;
|
||||
//
|
||||
// fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
// if s.is_empty() {
|
||||
// return Ok(Self::default());
|
||||
// }
|
||||
// let decimal = Decimal::from_str(s).map_err(internal_error)?;
|
||||
// Ok(Self::from_decimal(decimal))
|
||||
// }
|
||||
// }
|
||||
fn extract_number(num_str: &str) -> String {
|
||||
let mut matches = EXTRACT_NUM_REGEX.find_iter(num_str);
|
||||
let mut values = vec![];
|
||||
while let Some(Ok(m)) = matches.next() {
|
||||
values.push(m.as_str().to_string());
|
||||
}
|
||||
values.join("")
|
||||
}
|
||||
|
||||
impl ToString for NumberCellFormat {
|
||||
fn to_string(&self) -> String {
|
||||
@ -108,7 +104,7 @@ impl CellProtobufBlobParser for NumberCellDataParser {
|
||||
type Object = NumberCellFormat;
|
||||
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
match String::from_utf8(bytes.to_vec()) {
|
||||
Ok(s) => NumberCellFormat::from_format_str(&s, true, &NumberFormat::Num),
|
||||
Ok(s) => NumberCellFormat::from_format_str(&s, &NumberFormat::Num),
|
||||
Err(_) => Ok(NumberCellFormat::default()),
|
||||
}
|
||||
}
|
||||
@ -119,7 +115,7 @@ impl CellBytesCustomParser for NumberCellCustomDataParser {
|
||||
type Object = NumberCellFormat;
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
match String::from_utf8(bytes.to_vec()) {
|
||||
Ok(s) => NumberCellFormat::from_format_str(&s, true, &self.0),
|
||||
Ok(s) => NumberCellFormat::from_format_str(&s, &self.0),
|
||||
Err(_) => Ok(NumberCellFormat::default()),
|
||||
}
|
||||
}
|
||||
|
@ -141,12 +141,12 @@ where
|
||||
|
||||
let cell_data = self.decode_cell_str(cell, decoded_field_type, field)?;
|
||||
if let Some(cell_data_cache) = self.cell_data_cache.as_ref() {
|
||||
tracing::trace!(
|
||||
"Cell cache update: field_type:{}, cell: {:?}, cell_data: {:?}",
|
||||
decoded_field_type,
|
||||
cell,
|
||||
cell_data
|
||||
);
|
||||
// tracing::trace!(
|
||||
// "Cell cache update: field_type:{}, cell: {:?}, cell_data: {:?}",
|
||||
// decoded_field_type,
|
||||
// cell,
|
||||
// cell_data
|
||||
// );
|
||||
cell_data_cache
|
||||
.write()
|
||||
.insert(key.as_ref(), cell_data.clone());
|
||||
@ -163,12 +163,12 @@ where
|
||||
if let Some(cell_data_cache) = self.cell_data_cache.as_ref() {
|
||||
let field_type = FieldType::from(field.field_type);
|
||||
let key = CellDataCacheKey::new(field, field_type.clone(), cell);
|
||||
tracing::trace!(
|
||||
"Cell cache update: field_type:{}, cell: {:?}, cell_data: {:?}",
|
||||
field_type,
|
||||
cell,
|
||||
cell_data
|
||||
);
|
||||
// tracing::trace!(
|
||||
// "Cell cache update: field_type:{}, cell: {:?}, cell_data: {:?}",
|
||||
// field_type,
|
||||
// cell,
|
||||
// cell_data
|
||||
// );
|
||||
cell_data_cache.write().insert(key.as_ref(), cell_data);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use std::sync::Arc;
|
||||
/// * `configuration_writer`: as writer used to write the group configuration to disk
|
||||
///
|
||||
#[tracing::instrument(
|
||||
level = "debug",
|
||||
level = "trace",
|
||||
skip_all,
|
||||
fields(grouping_field_id=%grouping_field.id, grouping_field_type)
|
||||
err
|
||||
|
@ -85,7 +85,7 @@ impl SortController {
|
||||
self.gen_task(task_type, QualityOfService::Background).await;
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "process_sort_task", level = "trace", skip_all, err)]
|
||||
#[tracing::instrument(name = "process_sort_task", level = "debug", skip_all, err)]
|
||||
pub async fn process(&mut self, predicate: &str) -> FlowyResult<()> {
|
||||
let event_type = SortEvent::from_str(predicate).unwrap();
|
||||
let mut rows = self.delegate.get_rows(&self.view_id).await;
|
||||
|
@ -3,7 +3,6 @@ use lib_dispatch::prelude::AFPluginData;
|
||||
|
||||
use crate::entities::NetworkStatePB;
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
pub async fn update_network_ty(_data: AFPluginData<NetworkStatePB>) -> Result<(), FlowyError> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ thread-id = "3.3.0"
|
||||
log = "0.4"
|
||||
bytes = "1.4"
|
||||
nanoid = "0.4.0"
|
||||
tempdir = "0.3.7"
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = "1.0.3"
|
||||
|
@ -9,7 +9,8 @@ use flowy_user::{
|
||||
event_map::UserEvent::{InitUser, SignIn, SignOut, SignUp},
|
||||
};
|
||||
use lib_dispatch::prelude::{AFPluginDispatcher, AFPluginRequest, ToBytes};
|
||||
use std::{fs, path::PathBuf, sync::Arc};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct ViewTest {
|
||||
pub sdk: FlowySDKTest,
|
||||
@ -118,21 +119,6 @@ async fn create_view(
|
||||
.parse::<ViewPB>()
|
||||
}
|
||||
|
||||
pub fn root_dir() -> String {
|
||||
// https://doc.rust-lang.org/cargo/reference/environment-variables.html
|
||||
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| "./".to_owned());
|
||||
let mut path_buf = fs::canonicalize(&PathBuf::from(&manifest_dir)).unwrap();
|
||||
path_buf.pop(); // rust-lib
|
||||
path_buf.push("temp");
|
||||
path_buf.push("flowy");
|
||||
|
||||
let root_dir = path_buf.to_str().unwrap().to_string();
|
||||
if !std::path::Path::new(&root_dir).exists() {
|
||||
std::fs::create_dir_all(&root_dir).unwrap();
|
||||
}
|
||||
root_dir
|
||||
}
|
||||
|
||||
pub fn random_email() -> String {
|
||||
format!("{}@appflowy.io", nanoid!(20))
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use nanoid::nanoid;
|
||||
use std::env::temp_dir;
|
||||
|
||||
use flowy_core::{AppFlowyCore, AppFlowyCoreConfig};
|
||||
use flowy_net::http_server::self_host::configuration::get_client_server_configuration;
|
||||
@ -37,8 +38,8 @@ impl std::default::Default for FlowySDKTest {
|
||||
impl FlowySDKTest {
|
||||
pub fn new() -> Self {
|
||||
let server_config = get_client_server_configuration().unwrap();
|
||||
let config =
|
||||
AppFlowyCoreConfig::new(&root_dir(), nanoid!(6), server_config).log_filter("info", vec![]);
|
||||
let config = AppFlowyCoreConfig::new(temp_dir().to_str().unwrap(), nanoid!(6), server_config)
|
||||
.log_filter("info", vec![]);
|
||||
let sdk = std::thread::spawn(|| AppFlowyCore::new(config))
|
||||
.join()
|
||||
.unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user