collab: Fix project sharing between Windows and Unix (#23680)

Closes #14258

Windows user(host) sharing a project to a guest(using macOS), and host
follows guest:


https://github.com/user-attachments/assets/ba306b6b-23f7-48b1-8ba8-fdc5992d8f00

macOS user(host) sharing a project to a guest(using Windows), and host
follows guest:



https://github.com/user-attachments/assets/c5ee5e78-870d-49e5-907d-8565977a01ae

macOS user edits files in a windows project through collab:



https://github.com/user-attachments/assets/581057cf-e7df-4e56-a0ce-ced74339906a





Release Notes:

- N/A
This commit is contained in:
张小白 2025-02-11 08:12:01 +08:00 committed by GitHub
parent 929c5e76b4
commit c1f162abc6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 226 additions and 117 deletions

View file

@ -15,6 +15,8 @@ use std::{
cmp,
fmt::{self, Debug},
iter, mem,
path::{Path, PathBuf},
sync::Arc,
time::{Duration, SystemTime, UNIX_EPOCH},
};
@ -137,6 +139,62 @@ impl fmt::Display for PeerId {
}
}
pub trait FromProto {
fn from_proto(proto: String) -> Self;
}
pub trait ToProto {
fn to_proto(self) -> String;
}
impl FromProto for PathBuf {
#[cfg(target_os = "windows")]
fn from_proto(proto: String) -> Self {
proto.split("/").collect()
}
#[cfg(not(target_os = "windows"))]
fn from_proto(proto: String) -> Self {
PathBuf::from(proto)
}
}
impl FromProto for Arc<Path> {
fn from_proto(proto: String) -> Self {
PathBuf::from_proto(proto).into()
}
}
impl ToProto for PathBuf {
#[cfg(target_os = "windows")]
fn to_proto(self) -> String {
self.components()
.map(|comp| comp.as_os_str().to_string_lossy().to_string())
.collect::<Vec<_>>()
.join("/")
}
#[cfg(not(target_os = "windows"))]
fn to_proto(self) -> String {
self.to_string_lossy().to_string()
}
}
impl ToProto for &Path {
#[cfg(target_os = "windows")]
fn to_proto(self) -> String {
self.components()
.map(|comp| comp.as_os_str().to_string_lossy().to_string())
.collect::<Vec<_>>()
.join("/")
}
#[cfg(not(target_os = "windows"))]
fn to_proto(self) -> String {
self.to_string_lossy().to_string()
}
}
messages!(
(AcceptTermsOfService, Foreground),
(AcceptTermsOfServiceResponse, Foreground),
@ -757,4 +815,22 @@ mod tests {
};
assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
}
#[test]
#[cfg(target_os = "windows")]
fn test_proto() {
fn generate_proto_path(path: PathBuf) -> PathBuf {
let proto = path.to_proto();
PathBuf::from_proto(proto)
}
let path = PathBuf::from("C:\\foo\\bar");
assert_eq!(path, generate_proto_path(path.clone()));
let path = PathBuf::from("C:/foo/bar/");
assert_eq!(path, generate_proto_path(path.clone()));
let path = PathBuf::from("C:/foo\\bar\\");
assert_eq!(path, generate_proto_path(path.clone()));
}
}