AppFlowy/frontend/rust-lib/flowy-document/src/entities.rs

672 lines
15 KiB
Rust
Raw Normal View History

use std::collections::HashMap;
use collab::core::collab_state::SyncState;
use collab_document::{
blocks::{json_str_to_hashmap, Block, BlockAction, DocumentData},
document_awareness::{
DocumentAwarenessPosition, DocumentAwarenessSelection, DocumentAwarenessState,
DocumentAwarenessUser,
},
};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use lib_infra::validator_fn::{required_not_empty_str, required_valid_path};
use validator::Validate;
use crate::parse::{NotEmptyStr, NotEmptyVec};
feat: support publish document (#5576) * feat: support a event for getting encoded collab of document * feat: support publish view and unpublish views * feat: publish page to the web * chore: refacotor share bloc * feat: call the publish event * feat: support publish view and unpublish views * feat: integrate publish api * feat: integrate unpublish api * feat: fetch the publish info to show the publish status * feat: support publish interfaces * fix: lint error * fix: modified web server * fix: some style * fix: some style * fix: some style * fix: some style * fix: some style * fix: some style * fix: some style * fix: some style * fix: some style * fix: update codes * fix: update codes * fix: update codes * fix: update codes * fix: update codes * chore: refactor publish bloc * fix: some style * fix: some style * fix: some style * fix: some style * fix: some style * fix: some style * fix: the name is too long to publish * chore: change color * fix: some style * fix: some style * feat: refacotor share menu UI * fix: some style * fix: lint * fix: some style * feat: refacotor export-as * fix: some style * chore: refactor share menu colors * fix: rust ci * fix: some style * fix: some style * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: bugs * fix: rerelease * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: deploy * fix: og image * fix: support copy button * fix: support copy button * fix: support copy button * chore: add a params * feat: use default publish name * chore: update copy * feat: show a confirm deletion dialog if the deleted page contains published page * feat: add copy toast in publish tab * fix: to 404 fix: to 404 fix: to 404 fix: the error to 404 * feat: unpublish the page auto when moving it to another space * feat: improve confirm deletion dialog * feat: show unpublish error * chore: use beta.appflowy.com * feat: disable publish in non-apppflowy-cloud user mode * fix: modified bullted icon style * fix: the dark mode color * fix: save the dark mode in local storage * fix: text color * chore: make bash script more portable (#5679) * fix: title longer * chore: move the files and modified the en * chore: update deploy.sh * chore: modified Dockerfile * chore: modified server.cjs to server.js * chore: modifed server.js to server.ts * chore: replace publish url * chore: remove todo list hover * chore: show confirm dialog before deleting page * fix: unpublish the pages before deleting * fix: table cell bg color * fix: callout icon * fix: list number * fix: emoji * fix: number icon * fix: callout icon position * fix: add margin bottom * fix: code block * fix: support scroll for breadcrumbs * fix: the breadcrumb doesn't update after moving page * fix: 0705 issues * fix: update publish status afer deleting page * chore: add hover effect for visit site button * fix: remove puiblish url text field enable border color * chore: update delete page copy * chore: enable debug category * fix: only render sidebar if the spaces are ready * fix: the breadcrumb doesn't update after moving page * fix: auto code * fix: add emoji * fix: add emoji * fix: favicon * fix: cypress test * fix: remove deploy ci * fix: default url * chore: revert launch.json * fix: docker ci * fix: change favicon * fix: flutter integration test * feat: add hover effect to share menu * chore: add a checkmark if the page has been published * chore: revert space deletion --------- Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io> Co-authored-by: Zack <speed2exe@live.com.sg>
2024-07-08 05:45:57 +00:00
#[derive(Default, ProtoBuf)]
pub struct EncodedCollabPB {
#[pb(index = 1)]
pub state_vector: Vec<u8>,
#[pb(index = 2)]
pub doc_state: Vec<u8>,
}
#[derive(Default, ProtoBuf)]
pub struct OpenDocumentPayloadPB {
#[pb(index = 1)]
pub document_id: String,
}
pub struct OpenDocumentParams {
pub document_id: String,
}
impl TryInto<OpenDocumentParams> for OpenDocumentPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<OpenDocumentParams, Self::Error> {
let document_id =
NotEmptyStr::parse(self.document_id).map_err(|_| ErrorCode::DocumentIdIsEmpty)?;
Ok(OpenDocumentParams {
document_id: document_id.0,
})
}
}
#[derive(Default, ProtoBuf)]
pub struct DocumentRedoUndoPayloadPB {
#[pb(index = 1)]
pub document_id: String,
}
pub struct DocumentRedoUndoParams {
pub document_id: String,
}
impl TryInto<DocumentRedoUndoParams> for DocumentRedoUndoPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<DocumentRedoUndoParams, Self::Error> {
let document_id =
NotEmptyStr::parse(self.document_id).map_err(|_| ErrorCode::DocumentIdIsEmpty)?;
Ok(DocumentRedoUndoParams {
document_id: document_id.0,
})
}
}
#[derive(Default, Debug, ProtoBuf)]
pub struct DocumentRedoUndoResponsePB {
#[pb(index = 1)]
pub can_undo: bool,
#[pb(index = 2)]
pub can_redo: bool,
#[pb(index = 3)]
pub is_success: bool,
}
#[derive(Default, ProtoBuf, Validate)]
pub struct UploadFileParamsPB {
#[pb(index = 1)]
#[validate(custom = "required_not_empty_str")]
pub workspace_id: String,
#[pb(index = 2)]
#[validate(custom = "required_not_empty_str")]
pub document_id: String,
#[pb(index = 3)]
#[validate(custom = "required_valid_path")]
pub local_file_path: String,
}
#[derive(Default, ProtoBuf, Validate)]
pub struct UploadedFilePB {
#[pb(index = 1)]
#[validate(url)]
pub url: String,
#[pb(index = 2)]
#[validate(custom = "required_valid_path")]
pub local_file_path: String,
}
feat: ai billing (#5741) * feat: start on AI plan+billing UI * chore: enable plan and billing * feat: cache workspace subscription + minor fixes (#5705) * feat: update api from billing * feat: add api for workspace subscription info (#5717) * feat: refactor and start integrating AI plans * feat: refine UI and add business logic for AI * feat: complete UIUX for AI and limits * chore: remove resolved todo * chore: localize remove addon dialog * chore: fix spacing issue for usage * fix: interpret subscription + usage on action * chore: update api for billing (#5735) * chore: update revisions * fix: remove subscription cache * fix: copy improvements + use consistent dialog * chore: update to the latest client api * feat: support updating billing period * Feat/ai billing cancel reason (#5752) * chore: add cancellation reason field * fix: ci add one retry for concurrent sign up * chore: merge with main * chore: half merge * chore: fix conflict * chore: observer error * chore: remove unneeded protobuf and remove unwrap * feat: added subscription plan details * chore: check error code and update sidebar toast * chore: periodically check billing state * chore: editor ai error * chore: return file upload error * chore: fmt * chore: clippy * chore: disable upload image when exceed storage limitation * chore: remove todo * chore: remove openai i18n * chore: update log * chore: update client-api to fix stream error * chore: clippy * chore: fix language file * chore: disable billing UI --------- Co-authored-by: Zack Fu Zi Xiang <speed2exe@live.com.sg> Co-authored-by: nathan <nathan@appflowy.io>
2024-07-22 07:43:48 +00:00
#[derive(Default, ProtoBuf, Validate)]
pub struct DownloadFilePB {
#[pb(index = 1)]
#[validate(url)]
pub url: String,
#[pb(index = 2)]
#[validate(custom = "required_valid_path")]
pub local_file_path: String,
}
#[derive(Default, ProtoBuf)]
pub struct CreateDocumentPayloadPB {
#[pb(index = 1)]
pub document_id: String,
#[pb(index = 2, one_of)]
pub initial_data: Option<DocumentDataPB>,
}
pub struct CreateDocumentParams {
pub document_id: String,
pub initial_data: Option<DocumentData>,
}
impl TryInto<CreateDocumentParams> for CreateDocumentPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateDocumentParams, Self::Error> {
let document_id =
NotEmptyStr::parse(self.document_id).map_err(|_| ErrorCode::DocumentIdIsEmpty)?;
let initial_data = self.initial_data.map(|data| data.into());
Ok(CreateDocumentParams {
document_id: document_id.0,
initial_data,
})
}
}
#[derive(Default, ProtoBuf)]
pub struct CloseDocumentPayloadPB {
#[pb(index = 1)]
pub document_id: String,
}
pub struct CloseDocumentParams {
pub document_id: String,
}
impl TryInto<CloseDocumentParams> for CloseDocumentPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<CloseDocumentParams, Self::Error> {
let document_id =
NotEmptyStr::parse(self.document_id).map_err(|_| ErrorCode::DocumentIdIsEmpty)?;
Ok(CloseDocumentParams {
document_id: document_id.0,
})
}
}
#[derive(Default, ProtoBuf, Debug)]
pub struct ApplyActionPayloadPB {
#[pb(index = 1)]
pub document_id: String,
#[pb(index = 2)]
pub actions: Vec<BlockActionPB>,
}
pub struct ApplyActionParams {
feat: integrate new editor (#2536) * feat: update editor * feat: integrate new editor * feat: integrate the document2 into folder2 * feat: integrate the new editor * chore: cargo fix * chore: active document feature for flowy-error * feat: convert the editor action to collab action * feat: migrate the grid and board * feat: migrate the callout block * feat: migrate the divider * chore: migrate the callout and math equation * feat: migrate the code block * feat: add shift + enter command in code block * feat: support tab and shift+tab in code block * fix: cursor error after inserting divider * feat: migrate the grid and board * feat: migrate the emoji picker * feat: migrate openai * feat: integrate floating toolbar * feat: migrate the smart editor * feat: migrate the cover * feat: add option block action * chore: implement block selection and delete option * feat: support background color * feat: dismiss color picker afer setting color * feat: migrate the cover block * feat: resize the font * chore: cutomsize the padding * chore: wrap the option button with ignore widget * feat: customize the heading style * chore: optimize the divider line height * fix: the option button can't dismiss * ci: rust test * chore: flutter analyze * fix: code block selection * fix: dismiss the emoji picker after selecting one * chore: optimize the transaction adapter * fix: can't save the new content * feat: show export page when some errors happen * feat: implement get_view_data for document --------- Co-authored-by: nathan <nathan@appflowy.io>
2023-05-16 06:58:24 +00:00
pub document_id: String,
pub actions: Vec<BlockAction>,
}
impl TryInto<ApplyActionParams> for ApplyActionPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<ApplyActionParams, Self::Error> {
let document_id =
NotEmptyStr::parse(self.document_id).map_err(|_| ErrorCode::DocumentIdIsEmpty)?;
let actions = NotEmptyVec::parse(self.actions).map_err(|_| ErrorCode::ApplyActionsIsEmpty)?;
let actions = actions.0.into_iter().map(BlockAction::from).collect();
Ok(ApplyActionParams {
document_id: document_id.0,
actions,
})
}
feat: integrate new editor (#2536) * feat: update editor * feat: integrate new editor * feat: integrate the document2 into folder2 * feat: integrate the new editor * chore: cargo fix * chore: active document feature for flowy-error * feat: convert the editor action to collab action * feat: migrate the grid and board * feat: migrate the callout block * feat: migrate the divider * chore: migrate the callout and math equation * feat: migrate the code block * feat: add shift + enter command in code block * feat: support tab and shift+tab in code block * fix: cursor error after inserting divider * feat: migrate the grid and board * feat: migrate the emoji picker * feat: migrate openai * feat: integrate floating toolbar * feat: migrate the smart editor * feat: migrate the cover * feat: add option block action * chore: implement block selection and delete option * feat: support background color * feat: dismiss color picker afer setting color * feat: migrate the cover block * feat: resize the font * chore: cutomsize the padding * chore: wrap the option button with ignore widget * feat: customize the heading style * chore: optimize the divider line height * fix: the option button can't dismiss * ci: rust test * chore: flutter analyze * fix: code block selection * fix: dismiss the emoji picker after selecting one * chore: optimize the transaction adapter * fix: can't save the new content * feat: show export page when some errors happen * feat: implement get_view_data for document --------- Co-authored-by: nathan <nathan@appflowy.io>
2023-05-16 06:58:24 +00:00
}
#[derive(Default, Debug, ProtoBuf)]
pub struct DocumentDataPB {
#[pb(index = 1)]
pub page_id: String,
#[pb(index = 2)]
2023-04-13 12:30:28 +00:00
pub blocks: HashMap<String, BlockPB>,
#[pb(index = 3)]
pub meta: MetaPB,
}
#[derive(Default, Debug, ProtoBuf)]
pub struct DocumentTextPB {
#[pb(index = 1)]
pub text: String,
}
2023-07-04 09:17:25 +00:00
#[derive(Default, ProtoBuf, Debug, Clone)]
pub struct BlockPB {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub ty: String,
#[pb(index = 3)]
pub data: String,
#[pb(index = 4)]
pub parent_id: String,
#[pb(index = 5)]
pub children_id: String,
#[pb(index = 6, one_of)]
pub external_id: Option<String>,
#[pb(index = 7, one_of)]
pub external_type: Option<String>,
}
impl From<BlockPB> for Block {
fn from(pb: BlockPB) -> Self {
// Use `json_str_to_hashmap()` from the `collab_document` crate to convert the JSON data to a hashmap
let data = json_str_to_hashmap(&pb.data).unwrap_or_default();
// Convert the protobuf `BlockPB` to our internal `Block` struct
Self {
id: pb.id,
ty: pb.ty,
children: pb.children_id,
parent: pb.parent_id,
data,
external_id: pb.external_id,
external_type: pb.external_type,
}
}
}
#[derive(Default, ProtoBuf, Debug)]
pub struct MetaPB {
#[pb(index = 1)]
pub children_map: HashMap<String, ChildrenPB>,
#[pb(index = 2)]
pub text_map: HashMap<String, String>,
}
#[derive(Default, ProtoBuf, Debug)]
pub struct ChildrenPB {
#[pb(index = 1)]
pub children: Vec<String>,
}
// Actions
#[derive(Default, ProtoBuf, Debug)]
pub struct BlockActionPB {
#[pb(index = 1)]
pub action: BlockActionTypePB,
#[pb(index = 2)]
pub payload: BlockActionPayloadPB,
}
#[derive(Default, ProtoBuf, Debug)]
pub struct BlockActionPayloadPB {
// When action = Insert, Update, Delete or Move, block needs to be passed.
#[pb(index = 1, one_of)]
pub block: Option<BlockPB>,
// When action = Insert or Move, prev_id needs to be passed.
#[pb(index = 2, one_of)]
pub prev_id: Option<String>,
// When action = Insert or Move, parent_id needs to be passed.
#[pb(index = 3, one_of)]
pub parent_id: Option<String>,
// When action = InsertText or ApplyTextDelta, text_id needs to be passed.
#[pb(index = 4, one_of)]
pub text_id: Option<String>,
// When action = InsertText or ApplyTextDelta, delta needs to be passed.
// The format of delta is a JSON string, similar to the serialization result of [{ "insert": "Hello World" }].
#[pb(index = 5, one_of)]
pub delta: Option<String>,
}
#[derive(ProtoBuf_Enum, Debug)]
pub enum BlockActionTypePB {
Insert = 0,
Update = 1,
Delete = 2,
Move = 3,
InsertText = 4,
ApplyTextDelta = 5,
}
impl Default for BlockActionTypePB {
fn default() -> Self {
Self::Insert
}
}
#[derive(ProtoBuf_Enum)]
pub enum DeltaTypePB {
Inserted = 0,
Updated = 1,
Removed = 2,
}
impl Default for DeltaTypePB {
fn default() -> Self {
Self::Inserted
}
}
#[derive(Default, ProtoBuf)]
pub struct DocEventPB {
#[pb(index = 1)]
pub events: Vec<BlockEventPB>,
#[pb(index = 2)]
pub is_remote: bool,
#[pb(index = 3, one_of)]
pub new_snapshot: Option<DocumentDataPB>,
}
#[derive(Default, ProtoBuf)]
pub struct BlockEventPB {
#[pb(index = 1)]
pub event: Vec<BlockEventPayloadPB>,
}
#[derive(Default, ProtoBuf)]
pub struct BlockEventPayloadPB {
#[pb(index = 1)]
pub command: DeltaTypePB,
#[pb(index = 2)]
pub path: Vec<String>,
#[pb(index = 3)]
pub id: String,
#[pb(index = 4)]
pub value: String,
}
#[derive(PartialEq, Eq, Debug, ProtoBuf_Enum, Clone, Default)]
pub enum ExportType {
#[default]
Text = 0,
Markdown = 1,
Link = 2,
HTML = 3,
}
impl From<i32> for ExportType {
fn from(val: i32) -> Self {
match val {
0 => ExportType::Text,
1 => ExportType::Markdown,
2 => ExportType::Link,
3 => ExportType::HTML,
_ => {
tracing::error!("🔴Invalid export type: {}", val);
ExportType::Text
},
}
}
}
#[derive(Default, ProtoBuf)]
pub struct EditPayloadPB {
#[pb(index = 1)]
pub doc_id: String,
// Encode in JSON format
#[pb(index = 2)]
pub operations: String,
}
#[derive(Default, ProtoBuf)]
pub struct ExportDataPB {
#[pb(index = 1)]
pub data: String,
#[pb(index = 2)]
pub export_type: ExportType,
}
#[derive(PartialEq, Eq, Debug, ProtoBuf_Enum, Clone, Default)]
pub enum ConvertType {
#[default]
Json = 0,
}
impl From<i32> for ConvertType {
fn from(val: i32) -> Self {
match val {
0 => ConvertType::Json,
_ => {
tracing::error!("🔴Invalid export type: {}", val);
ConvertType::Json
},
}
}
}
/// for convert data to document
/// for the json type
/// the data is the json string
#[derive(Default, ProtoBuf, Debug)]
pub struct ConvertDataPayloadPB {
#[pb(index = 1)]
pub convert_type: ConvertType,
#[pb(index = 2)]
pub data: Vec<u8>,
}
pub struct ConvertDataParams {
pub convert_type: ConvertType,
pub data: Vec<u8>,
}
impl TryInto<ConvertDataParams> for ConvertDataPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<ConvertDataParams, Self::Error> {
let convert_type = self.convert_type;
let data = self.data;
Ok(ConvertDataParams { convert_type, data })
}
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedDocumentSnapshotMetaPB {
#[pb(index = 1)]
pub items: Vec<DocumentSnapshotMetaPB>,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct DocumentSnapshotMetaPB {
#[pb(index = 1)]
pub snapshot_id: String,
#[pb(index = 2)]
pub object_id: String,
#[pb(index = 3)]
pub created_at: i64,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct DocumentSnapshotPB {
#[pb(index = 1)]
pub object_id: String,
#[pb(index = 2)]
pub encoded_v1: Vec<u8>,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct DocumentSnapshotStatePB {
#[pb(index = 1)]
pub new_snapshot_id: i64,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct DocumentSyncStatePB {
#[pb(index = 1)]
pub value: DocumentSyncState,
}
#[derive(Debug, Default, ProtoBuf_Enum, PartialEq, Eq, Clone, Copy)]
pub enum DocumentSyncState {
#[default]
InitSyncBegin = 0,
InitSyncEnd = 1,
Syncing = 2,
SyncFinished = 3,
}
impl From<SyncState> for DocumentSyncStatePB {
fn from(value: SyncState) -> Self {
let value = match value {
SyncState::InitSyncBegin => DocumentSyncState::InitSyncBegin,
SyncState::InitSyncEnd => DocumentSyncState::InitSyncEnd,
SyncState::Syncing => DocumentSyncState::Syncing,
SyncState::SyncFinished => DocumentSyncState::SyncFinished,
};
Self { value }
}
}
#[derive(Default, ProtoBuf, Debug)]
pub struct TextDeltaPayloadPB {
#[pb(index = 1)]
pub document_id: String,
#[pb(index = 2)]
pub text_id: String,
#[pb(index = 3, one_of)]
pub delta: Option<String>,
}
pub struct TextDeltaParams {
pub document_id: String,
pub text_id: String,
pub delta: String,
}
impl TryInto<TextDeltaParams> for TextDeltaPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<TextDeltaParams, Self::Error> {
let document_id =
NotEmptyStr::parse(self.document_id).map_err(|_| ErrorCode::DocumentIdIsEmpty)?;
let text_id = NotEmptyStr::parse(self.text_id).map_err(|_| ErrorCode::TextIdIsEmpty)?;
let delta = self.delta.map_or_else(|| "".to_string(), |delta| delta);
Ok(TextDeltaParams {
document_id: document_id.0,
text_id: text_id.0,
delta,
})
}
}
pub struct DocumentSnapshotMeta {
pub snapshot_id: String,
pub object_id: String,
pub created_at: i64,
}
pub struct DocumentSnapshotData {
pub object_id: String,
pub encoded_v1: Vec<u8>,
}
#[derive(ProtoBuf, Debug, Default)]
pub struct DocumentAwarenessStatesPB {
#[pb(index = 1)]
pub value: HashMap<String, DocumentAwarenessStatePB>,
}
impl From<HashMap<u64, DocumentAwarenessState>> for DocumentAwarenessStatesPB {
fn from(value: HashMap<u64, DocumentAwarenessState>) -> Self {
let value = value
.into_iter()
.map(|(k, v)| (k.to_string(), v.into()))
.collect();
Self { value }
}
}
#[derive(ProtoBuf, Debug, Default)]
pub struct UpdateDocumentAwarenessStatePB {
#[pb(index = 1)]
pub document_id: String,
#[pb(index = 2, one_of)]
pub selection: Option<DocumentAwarenessSelectionPB>,
#[pb(index = 3, one_of)]
pub metadata: Option<String>,
}
#[derive(ProtoBuf, Debug, Default)]
pub struct DocumentAwarenessStatePB {
#[pb(index = 1)]
pub version: i64,
#[pb(index = 2)]
pub user: DocumentAwarenessUserPB,
#[pb(index = 3, one_of)]
pub selection: Option<DocumentAwarenessSelectionPB>,
#[pb(index = 4, one_of)]
pub metadata: Option<String>,
#[pb(index = 5)]
pub timestamp: i64,
}
impl From<DocumentAwarenessState> for DocumentAwarenessStatePB {
fn from(value: DocumentAwarenessState) -> Self {
DocumentAwarenessStatePB {
version: value.version,
user: value.user.into(),
selection: value.selection.map(|s| s.into()),
metadata: value.metadata,
timestamp: value.timestamp,
}
}
}
#[derive(ProtoBuf, Debug, Default)]
pub struct DocumentAwarenessUserPB {
#[pb(index = 1)]
pub uid: i64,
#[pb(index = 2)]
pub device_id: String,
}
impl From<DocumentAwarenessUser> for DocumentAwarenessUserPB {
fn from(value: DocumentAwarenessUser) -> Self {
DocumentAwarenessUserPB {
uid: value.uid,
device_id: value.device_id.to_string(),
}
}
}
#[derive(ProtoBuf, Debug, Default)]
pub struct DocumentAwarenessSelectionPB {
#[pb(index = 1)]
pub start: DocumentAwarenessPositionPB,
#[pb(index = 2)]
pub end: DocumentAwarenessPositionPB,
}
#[derive(ProtoBuf, Debug, Default)]
pub struct DocumentAwarenessPositionPB {
#[pb(index = 1)]
pub path: Vec<u64>,
#[pb(index = 2)]
pub offset: u64,
}
impl From<DocumentAwarenessSelectionPB> for DocumentAwarenessSelection {
fn from(value: DocumentAwarenessSelectionPB) -> Self {
DocumentAwarenessSelection {
start: value.start.into(),
end: value.end.into(),
}
}
}
impl From<DocumentAwarenessSelection> for DocumentAwarenessSelectionPB {
fn from(value: DocumentAwarenessSelection) -> Self {
DocumentAwarenessSelectionPB {
start: value.start.into(),
end: value.end.into(),
}
}
}
impl From<DocumentAwarenessPositionPB> for DocumentAwarenessPosition {
fn from(value: DocumentAwarenessPositionPB) -> Self {
DocumentAwarenessPosition {
path: value.path,
offset: value.offset,
}
}
}
impl From<DocumentAwarenessPosition> for DocumentAwarenessPositionPB {
fn from(value: DocumentAwarenessPosition) -> Self {
DocumentAwarenessPositionPB {
path: value.path,
offset: value.offset,
}
}
}