feat: merge different hosts

This commit is contained in:
Tien Do Nam
2026-08-01 22:18:37 +02:00
parent da4464def2
commit be9a53b64c
33 changed files with 757 additions and 394 deletions
+11 -24
View File
@@ -5,9 +5,8 @@ pub use store::{
};
use crate::http::client::{ClientError, LsHttpClientV2};
use crate::http::dto::ProtocolType;
use crate::http::dto_v2::{RegisterDtoV2, RegisterResponseDtoV2};
use crate::model::discovery::{MulticastMessageV2, ProtocolTypeV2};
use crate::model::discovery::{MulticastMessageV2, ProtocolType};
use crate::multicast::{
self, InterfaceFilter, MulticastConfig, MulticastDevice, MulticastEvent, MulticastHandle,
};
@@ -148,20 +147,20 @@ impl DiscoveryState {
client: &LsHttpClientV2,
host: &str,
port: u16,
protocol: ProtocolTypeV2,
protocol: ProtocolType,
) -> Result<Option<StatefulDevice>, ClientError> {
let response = client
.register(client_protocol(protocol), host, port, self.register_dto())
.register(protocol, host, port, self.register_dto())
.await?;
// In HTTPS mode the certificate is the peer's identity; the
// fingerprint claimed in the body only counts without encryption.
let fingerprint = match protocol {
ProtocolTypeV2::Https => response
ProtocolType::Https => response
.cert_fingerprint
.clone()
.ok_or_else(|| anyhow::anyhow!("HTTPS response carried no peer certificate"))?,
ProtocolTypeV2::Http => response.body.fingerprint.clone(),
ProtocolType::Http => response.body.fingerprint.clone(),
};
if fingerprint == self.device.fingerprint {
return Ok(None);
@@ -233,7 +232,7 @@ impl DiscoveryHandle {
&self,
host: &str,
port: u16,
protocol: ProtocolTypeV2,
protocol: ProtocolType,
) -> Result<Option<StatefulDevice>, ClientError> {
let client = self.state.unpinned_client()?;
self.state.probe(&client, host, port, protocol).await
@@ -249,7 +248,7 @@ impl DiscoveryHandle {
&self,
interface_ip: Ipv4Addr,
port: u16,
protocol: ProtocolTypeV2,
protocol: ProtocolType,
) -> Result<Vec<StatefulDevice>, ClientError> {
if !self.state.scanning.lock().unwrap().insert(interface_ip) {
return Ok(Vec::new());
@@ -414,8 +413,8 @@ async fn answer_announcement(
// Pin the claimed fingerprint, so nothing is sent to a device that does
// not hold the matching certificate.
let expected_fingerprint = match message.protocol {
ProtocolTypeV2::Https => Some(message.fingerprint.clone()),
ProtocolTypeV2::Http => None,
ProtocolType::Https => Some(message.fingerprint.clone()),
ProtocolType::Http => None,
};
let client = match LsHttpClientV2::try_new(
&state.identity.private_key_pem,
@@ -431,12 +430,7 @@ async fn answer_announcement(
};
let result = client
.register(
client_protocol(message.protocol),
&host,
message.port,
state.register_dto(),
)
.register(message.protocol, &host, message.port, state.register_dto())
.await;
match result {
@@ -464,7 +458,7 @@ fn confirmed_device(
response: RegisterResponseDtoV2,
host: String,
port: u16,
protocol: ProtocolTypeV2,
protocol: ProtocolType,
fingerprint: String,
) -> DiscoveredDevice {
DiscoveredDevice {
@@ -481,10 +475,3 @@ fn confirmed_device(
download: response.download,
}
}
fn client_protocol(protocol: ProtocolTypeV2) -> ProtocolType {
match protocol {
ProtocolTypeV2::Http => ProtocolType::Http,
ProtocolTypeV2::Https => ProtocolType::Https,
}
}
+3 -3
View File
@@ -1,7 +1,7 @@
//! The in-memory store of discovered devices.
use super::DiscoveryEvent;
use crate::model::discovery::{DeviceType, ProtocolTypeV2};
use crate::model::discovery::{DeviceType, ProtocolType};
use std::collections::HashMap;
use std::net::IpAddr;
use std::sync::Mutex;
@@ -157,7 +157,7 @@ pub struct HttpChannel {
pub port: u16,
/// Whether the HTTP server uses TLS.
pub protocol: ProtocolTypeV2,
pub protocol: ProtocolType,
}
/// All devices discovered in this run, identified by fingerprint, in
@@ -262,7 +262,7 @@ mod tests {
channel: DeviceChannel::Http(HttpChannel {
host: host.to_string(),
port: 53317,
protocol: ProtocolTypeV2::Https,
protocol: ProtocolType::Https,
}),
download: false,
}
+4 -4
View File
@@ -84,7 +84,7 @@ impl LsHttpClient {
pub async fn register(
&self,
protocol: http::dto::ProtocolType,
protocol: model::discovery::ProtocolType,
ip: &str,
port: u16,
payload: http::dto::RegisterDto,
@@ -104,7 +104,7 @@ impl LsHttpClient {
pub async fn prepare_upload(
&self,
protocol: http::dto::ProtocolType,
protocol: model::discovery::ProtocolType,
ip: &str,
port: u16,
public_key: Option<String>,
@@ -129,7 +129,7 @@ impl LsHttpClient {
pub async fn upload(
&self,
protocol: http::dto::ProtocolType,
protocol: model::discovery::ProtocolType,
ip: &str,
port: u16,
public_key: Option<String>,
@@ -161,7 +161,7 @@ impl LsHttpClient {
pub async fn cancel(
&self,
protocol: http::dto::ProtocolType,
protocol: model::discovery::ProtocolType,
ip: &str,
port: u16,
session_id: &str,
+1 -1
View File
@@ -1,10 +1,10 @@
use super::{ClientError, ResponseExt, ResultWithPublicKey};
use crate::http::client::url::{ApiVersion, TargetUrl};
use crate::http::dto::ProtocolType;
use crate::http::dto_v2::{
InfoResponseDtoV2, PrepareDownloadResponseDtoV2, PrepareUploadRequestDtoV2,
PrepareUploadResponseDtoV2, PrepareUploadResultV2, RegisterDtoV2, RegisterResponseDtoV2,
};
use crate::model::discovery::ProtocolType;
use futures_util::StreamExt;
use reqwest::{Response, StatusCode};
use tokio::io::AsyncWriteExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use super::{ClientError, ResponseExt, ResultWithPublicKey};
use crate::http;
use crate::http::client::url::{ApiVersion, TargetUrl};
use crate::http::dto::ProtocolType;
use crate::model::discovery::ProtocolType;
use crate::{crypto, util};
use lru::LruCache;
use reqwest::{Response, StatusCode};
+3 -28
View File
@@ -1,8 +1,8 @@
use crate::http::dto_v2::{
PrepareUploadRequestDtoV2, PrepareUploadResponseDtoV2, ProtocolTypeV2, RegisterDtoV2,
RegisterResponseDtoV2,
PrepareUploadRequestDtoV2, PrepareUploadResponseDtoV2, RegisterDtoV2, RegisterResponseDtoV2,
};
use crate::model::discovery::DeviceType;
use crate::model::discovery::ProtocolType;
use crate::model::transfer::FileDto;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@@ -48,31 +48,6 @@ pub struct RegisterDto {
pub has_web_interface: bool,
}
#[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ProtocolType {
Http,
Https,
}
impl ProtocolType {
pub fn as_str(&self) -> &'static str {
match self {
ProtocolType::Http => "http",
ProtocolType::Https => "https",
}
}
}
impl From<ProtocolType> for ProtocolTypeV2 {
fn from(p: ProtocolType) -> Self {
match p {
ProtocolType::Http => ProtocolTypeV2::Http,
ProtocolType::Https => ProtocolTypeV2::Https,
}
}
}
impl From<RegisterDto> for RegisterDtoV2 {
fn from(v3: RegisterDto) -> Self {
RegisterDtoV2 {
@@ -82,7 +57,7 @@ impl From<RegisterDto> for RegisterDtoV2 {
device_type: v3.device_type,
fingerprint: v3.token,
port: v3.port,
protocol: v3.protocol.into(),
protocol: v3.protocol,
download: v3.has_web_interface,
}
}
+6 -5
View File
@@ -6,8 +6,8 @@ use std::collections::HashMap;
// Discovery types are shared with the (HTTP-independent) multicast module and
// therefore live in `crate::model::discovery`. They are re-exported here so that
// the v2 DTOs remain available under a single path.
pub(crate) use crate::model::discovery::device_type_v2;
pub use crate::model::discovery::{MulticastMessageV2, ProtocolTypeV2, PROTOCOL_VERSION_V2};
use crate::model::discovery::ProtocolType;
use crate::model::discovery::{device_type_v2, protocol_type_v2};
/// Register request DTO for v2.1 protocol.
///
@@ -41,7 +41,8 @@ pub struct RegisterDtoV2 {
pub port: u16,
/// Protocol type (http or https).
pub protocol: ProtocolTypeV2,
#[serde(with = "protocol_type_v2")]
pub protocol: ProtocolType,
/// Whether the download API (sections 5.2, 5.3) is active.
#[serde(default)]
@@ -188,7 +189,7 @@ mod tests {
assert_eq!(dto.device_type, Some(DeviceType::Desktop));
assert_eq!(dto.fingerprint, "random string");
assert_eq!(dto.port, 53317);
assert_eq!(dto.protocol, ProtocolTypeV2::Https);
assert_eq!(dto.protocol, ProtocolType::Https);
assert!(dto.download);
}
@@ -232,7 +233,7 @@ mod tests {
device_type: None,
fingerprint: "sender-fingerprint".to_string(),
port: 53317,
protocol: ProtocolTypeV2::Https,
protocol: ProtocolType::Https,
download: false,
},
files: HashMap::from([(
+2 -1
View File
@@ -1,6 +1,6 @@
use crate::http::dto_v2::{
InfoResponseDtoV2, PrepareUploadRequestDtoV2, PrepareUploadResponseDtoV2, RegisterDtoV2,
RegisterResponseDtoV2, PROTOCOL_VERSION_V2,
RegisterResponseDtoV2,
};
use crate::http::server::common::collect_to_json::CollectToJson;
use crate::http::server::common::error::AppError;
@@ -13,6 +13,7 @@ use crate::http::server::common::session::{
};
use crate::http::server::PeerIp;
use crate::http::server::{common, AppState, RequestClientInfo, V2State};
use crate::model::discovery::PROTOCOL_VERSION_V2;
use crate::model::transfer::FileDto;
use hyper::body::Incoming;
use hyper::{Request, Response, StatusCode};
+2 -1
View File
@@ -1,10 +1,11 @@
use crate::http::dto_v2::{InfoResponseDtoV2, PrepareDownloadResponseDtoV2, PROTOCOL_VERSION_V2};
use crate::http::dto_v2::{InfoResponseDtoV2, PrepareDownloadResponseDtoV2};
use crate::http::server::common::error::AppError;
use crate::http::server::common::pin::check_pin;
use crate::http::server::common::query::parse_query;
use crate::http::server::common::response::{full_body, BoxedBody, JsonResponse};
use crate::http::server::PeerIp;
use crate::http::server::{AppState, RequestClientInfo};
use crate::model::discovery::PROTOCOL_VERSION_V2;
use crate::model::transfer::{FileContent, FileDto};
use bytes::Bytes;
use http_body_util::{BodyExt, StreamBody};
+39 -9
View File
@@ -15,17 +15,46 @@ pub enum DeviceType {
/// Protocol type for HTTP or HTTPS connections.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Serialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ProtocolTypeV2 {
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ProtocolType {
Http,
Https,
}
impl ProtocolTypeV2 {
impl ProtocolType {
pub fn as_str(&self) -> &'static str {
match self {
ProtocolTypeV2::Http => "http",
ProtocolTypeV2::Https => "https",
ProtocolType::Http => "http",
ProtocolType::Https => "https",
}
}
}
/// Serde helpers for `ProtocolType` in the v2 protocol.
///
/// The v2 protocol uses lowercase values ("http"/"https") on the wire.
pub(crate) mod protocol_type_v2 {
use super::ProtocolType;
use serde::{Deserialize, Deserializer, Serializer};
pub fn serialize<S: Serializer>(
value: &ProtocolType,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_str(value.as_str())
}
pub fn deserialize<'de, D: Deserializer<'de>>(
deserializer: D,
) -> Result<ProtocolType, D::Error> {
let value = String::deserialize(deserializer)?;
match value.as_str() {
"http" => Ok(ProtocolType::Http),
"https" => Ok(ProtocolType::Https),
_ => Err(serde::de::Error::unknown_variant(
&value,
&["http", "https"],
)),
}
}
}
@@ -103,7 +132,8 @@ pub struct MulticastMessageV2 {
pub port: u16,
/// Protocol type (http or https).
pub protocol: ProtocolTypeV2,
#[serde(with = "protocol_type_v2")]
pub protocol: ProtocolType,
/// Whether the download API (sections 5.2, 5.3) is active.
#[serde(default)]
@@ -123,7 +153,7 @@ mod tests {
device_type: Some(DeviceType::Mobile),
fingerprint: "random string".to_string(),
port: 53317,
protocol: ProtocolTypeV2::Https,
protocol: ProtocolType::Https,
download: true,
};
@@ -155,7 +185,7 @@ mod tests {
assert_eq!(msg.device_model, Some("Windows".to_string()));
assert_eq!(msg.device_type, Some(DeviceType::Desktop));
assert_eq!(msg.port, 53317);
assert_eq!(msg.protocol, ProtocolTypeV2::Https);
assert_eq!(msg.protocol, ProtocolType::Https);
assert!(msg.download);
}
@@ -172,7 +202,7 @@ mod tests {
let msg: MulticastMessageV2 = serde_json::from_str(json).unwrap();
assert_eq!(msg.device_model, None);
assert_eq!(msg.device_type, None);
assert_eq!(msg.protocol, ProtocolTypeV2::Http);
assert_eq!(msg.protocol, ProtocolType::Http);
assert!(!msg.download);
}
}
+3 -3
View File
@@ -13,7 +13,7 @@ mod socket;
pub use interface::InterfaceFilter;
use crate::model::discovery::{DeviceType, MulticastMessageV2, ProtocolTypeV2};
use crate::model::discovery::{DeviceType, MulticastMessageV2, ProtocolType};
use serde::Serialize;
use socket::MulticastSocket;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
@@ -85,7 +85,7 @@ pub struct MulticastDevice {
pub port: u16,
/// Whether this device's HTTP server uses TLS.
pub protocol: ProtocolTypeV2,
pub protocol: ProtocolType,
/// Whether this device's download API is active.
pub download: bool,
@@ -395,7 +395,7 @@ mod tests {
device_type: Some(DeviceType::Desktop),
fingerprint: "my-fingerprint".to_string(),
port: 53317,
protocol: ProtocolTypeV2::Https,
protocol: ProtocolType::Https,
download: false,
};
+10 -10
View File
@@ -14,7 +14,7 @@ use localsend::discovery::{
};
use localsend::http::server::{start_with_port, ServerConfigV2, TlsConfig};
use localsend::http::state::ClientInfo;
use localsend::model::discovery::{DeviceType, ProtocolTypeV2, PROTOCOL_VERSION_V2};
use localsend::model::discovery::{DeviceType, ProtocolType, PROTOCOL_VERSION_V2};
use localsend::multicast::{InterfaceFilter, MulticastDevice};
use std::net::{Ipv4Addr, Ipv6Addr};
use std::sync::atomic::{AtomicU16, Ordering};
@@ -149,7 +149,7 @@ async fn start_instance(
device_type: Some(DeviceType::Headless),
fingerprint: cert.fingerprint.clone(),
port: server_port,
protocol: ProtocolTypeV2::Http,
protocol: ProtocolType::Http,
download: false,
},
identity: DeviceIdentity {
@@ -191,7 +191,7 @@ async fn test_targeted_discovery_stores_and_emits_device() {
let device = instance
.handle
.discover("127.0.0.1", server_port, ProtocolTypeV2::Http)
.discover("127.0.0.1", server_port, ProtocolType::Http)
.await
.expect("Targeted discovery failed")
.expect("The target must not be mistaken for the device itself");
@@ -220,7 +220,7 @@ async fn test_targeted_discovery_stores_and_emits_device() {
// Discovering the same device again emits Updated instead of Discovered.
let updated = instance
.handle
.discover("127.0.0.1", server_port, ProtocolTypeV2::Http)
.discover("127.0.0.1", server_port, ProtocolType::Http)
.await
.expect("Targeted discovery failed")
.expect("The target must still be discoverable");
@@ -254,7 +254,7 @@ async fn test_targeted_discovery_does_not_discover_itself() {
let device = instance
.handle
.discover("127.0.0.1", server_port, ProtocolTypeV2::Http)
.discover("127.0.0.1", server_port, ProtocolType::Http)
.await
.expect("Targeted discovery failed");
@@ -281,7 +281,7 @@ async fn test_subnet_scan_finds_device_on_loopback() {
.scan_subnet(
Ipv4Addr::new(127, 0, 0, 99),
server_port,
ProtocolTypeV2::Http,
ProtocolType::Http,
)
.await
.expect("Subnet scan failed");
@@ -337,7 +337,7 @@ async fn test_targeted_discovery_reads_fingerprint_from_certificate_on_https() {
let device = instance
.handle
.discover("127.0.0.1", server_port, ProtocolTypeV2::Https)
.discover("127.0.0.1", server_port, ProtocolType::Https)
.await
.expect("Targeted discovery failed")
.expect("The target must not be mistaken for the device itself");
@@ -382,7 +382,7 @@ async fn test_discovery_works_without_multicast() {
device_type: Some(DeviceType::Headless),
fingerprint: cert.fingerprint.clone(),
port: free_port(),
protocol: ProtocolTypeV2::Http,
protocol: ProtocolType::Http,
download: false,
},
identity: DeviceIdentity {
@@ -404,7 +404,7 @@ async fn test_discovery_works_without_multicast() {
// Announcing is a no-op, the active operations still work.
handle.announce().await;
let device = handle
.discover("127.0.0.1", server_port, ProtocolTypeV2::Http)
.discover("127.0.0.1", server_port, ProtocolType::Http)
.await
.expect("Targeted discovery failed")
.expect("The target must not be mistaken for the device itself");
@@ -441,7 +441,7 @@ async fn test_announcement_is_answered_and_device_stored() {
assert_eq!(device.alias, "Announcer");
let http = device.http().expect("The device must have an HTTP channel");
assert_eq!(http.port, announcer_port);
assert_eq!(http.protocol, ProtocolTypeV2::Http);
assert_eq!(http.protocol, ProtocolType::Http);
assert!(
receiver
+3 -3
View File
@@ -6,7 +6,7 @@
//! interface, a firewall dropping the group), so these tests skip themselves
//! instead of failing when the environment does not carry the traffic.
use localsend::model::discovery::{DeviceType, ProtocolTypeV2, PROTOCOL_VERSION_V2};
use localsend::model::discovery::{DeviceType, ProtocolType, PROTOCOL_VERSION_V2};
use localsend::multicast::{
self, MulticastConfig, MulticastDevice, MulticastEvent, MulticastHandle,
};
@@ -88,7 +88,7 @@ async fn start_instance(alias: &str, port: u16) -> Option<TestInstance> {
device_type: Some(DeviceType::Headless),
fingerprint: format!("fingerprint-of-{alias}"),
port,
protocol: ProtocolTypeV2::Https,
protocol: ProtocolType::Https,
download: false,
},
event_tx,
@@ -215,7 +215,7 @@ async fn test_port_is_released_after_stop() {
device_type: None,
fingerprint: "fingerprint-of-Restarting".to_string(),
port,
protocol: ProtocolTypeV2::Http,
protocol: ProtocolType::Http,
download: false,
},
event_tx,
+3 -3
View File
@@ -4,12 +4,12 @@ use bytes::Bytes;
use futures_util::StreamExt;
use localsend::crypto::hash::sha256_hex;
use localsend::http::client::{ClientError, LsHttpClientV2};
use localsend::http::dto::ProtocolType;
use localsend::http::dto_v2::{PrepareUploadRequestDtoV2, ProtocolTypeV2, RegisterDtoV2};
use localsend::http::dto_v2::{PrepareUploadRequestDtoV2, RegisterDtoV2};
use localsend::http::server::common::save::FileUploadTarget;
use localsend::http::server::v2::{PrepareUploadDecisionV2, ServerEventV2, SessionEndReasonV2};
use localsend::http::server::{start_with_port, ServerConfigV2};
use localsend::http::state::ClientInfo;
use localsend::model::discovery::ProtocolType;
use localsend::model::transfer::{FileDto, FileMetadata};
use std::collections::HashMap;
use std::path::PathBuf;
@@ -178,7 +178,7 @@ fn sender_info() -> RegisterDtoV2 {
device_type: None,
fingerprint: "sender-fingerprint".to_string(),
port: 53317,
protocol: ProtocolTypeV2::Http,
protocol: ProtocolType::Http,
download: false,
}
}
+3 -3
View File
@@ -6,12 +6,12 @@
use bytes::Bytes;
use futures_util::StreamExt;
use localsend::http::client::{ClientError, LsHttpClientV2};
use localsend::http::dto::ProtocolType;
use localsend::http::dto_v2::{PrepareUploadRequestDtoV2, ProtocolTypeV2, RegisterDtoV2};
use localsend::http::dto_v2::{PrepareUploadRequestDtoV2, RegisterDtoV2};
use localsend::http::server::common::save::FileUploadTarget;
use localsend::http::server::v2::{PrepareUploadDecisionV2, ServerEventV2};
use localsend::http::server::{start_with_port, ServerConfigV2, TlsConfig};
use localsend::http::state::ClientInfo;
use localsend::model::discovery::ProtocolType;
use localsend::model::transfer::FileDto;
use std::sync::atomic::{AtomicU16, AtomicU64, Ordering};
use std::sync::Arc;
@@ -177,7 +177,7 @@ fn sender_info(fingerprint: &str) -> RegisterDtoV2 {
device_type: None,
fingerprint: fingerprint.to_string(),
port: 53317,
protocol: ProtocolTypeV2::Https,
protocol: ProtocolType::Https,
download: false,
}
}
+1 -1
View File
@@ -2,12 +2,12 @@
use bytes::Bytes;
use localsend::http::client::{ClientError, LsHttpClientV2};
use localsend::http::dto::ProtocolType;
use localsend::http::server::v2::ServerEventV2;
use localsend::http::server::web::WebSendConfig;
use localsend::http::server::web::{WebSendEvent, WebSendI18n};
use localsend::http::server::{start_with_port, ServerConfigV2};
use localsend::http::state::ClientInfo;
use localsend::model::discovery::ProtocolType;
use localsend::model::transfer::{FileContent, FileDto};
use std::collections::HashMap;
use std::net::IpAddr;
@@ -5,10 +5,9 @@
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
import 'package:localsend_isolates/rust/api/model.dart';
import 'package:localsend_isolates/rust/api/server.dart';
import 'package:localsend_isolates/rust/frb_generated.dart';
// These functions are ignored because they are not marked as `pub`: `rs_device`
// These functions are ignored because they are not marked as `pub`: `rs_stored_device`
/// Starts the discovery: binds the UDP multicast sockets on all usable
/// network interfaces, answers announcements of other devices with an HTTP
@@ -39,7 +38,7 @@ Future<RsDiscovery> startDiscovery({
String? deviceModel,
DeviceType? deviceType,
required String fingerprint,
required ProtocolTypeV2 protocol,
required ProtocolType protocol,
required bool download,
required String certPem,
required String privateKeyPem,
@@ -85,11 +84,11 @@ abstract class RsDiscovery implements RustOpaqueInterface {
/// The confirmed device is also emitted on [RsDiscovery::listen].
/// Returns `None` when the device did not answer or answered with this
/// device's own fingerprint (i.e. the device discovered itself).
Future<RsDiscoveredDevice?> discover({required String host, required int port, required ProtocolTypeV2 protocol});
Future<RsStoredDevice?> discover({required String host, required int port, required ProtocolType protocol});
/// Emits a [RsDiscoveredDevice] for every device confirmation until the
/// Emits a [RsStoredDevice] for every device confirmation until the
/// discovery is stopped. Can only be listened to once.
Stream<RsDiscoveredDevice> listen();
Stream<RsStoredDevice> listen();
/// The reason the multicast sockets could not be bound, when they could
/// not. Discovery then neither hears nor sends announcements.
@@ -103,7 +102,7 @@ abstract class RsDiscovery implements RustOpaqueInterface {
/// this method returns once the whole scan has finished. At most one scan
/// runs per interface: a call for an address that is still being scanned
/// returns immediately.
Future<void> scanSubnet({required String interfaceIp, required int port, required ProtocolTypeV2 protocol});
Future<void> scanSubnet({required String interfaceIp, required int port, required ProtocolType protocol});
/// Sets whether announcements of other devices are answered with a
/// register request (the answer is what makes the announcing device enter
@@ -118,12 +117,34 @@ abstract class RsDiscovery implements RustOpaqueInterface {
Future<void> stop();
}
/// A device that was confirmed over HTTP by the discovery: it answered a
/// register request, or its register request was accepted by our server and
/// was fed back via [RsDiscovery::add_device].
///
/// Emitted on [RsDiscovery::listen] for every confirmation, so a device
/// re-appears whenever it re-announces itself or is re-discovered.
/// An address a stored device was confirmed on and is dialed at.
class RsDeviceChannel {
/// The host to dial: an IP address, or the scoped form `fe80::1%3` for
/// link-local IPv6 (the Rust HTTP client accepts both back as a host).
final String host;
/// The port of the device's HTTP server at this address.
final int port;
final ProtocolType protocol;
const RsDeviceChannel({
required this.host,
required this.port,
required this.protocol,
});
@override
int get hashCode => host.hashCode ^ port.hashCode ^ protocol.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is RsDeviceChannel && runtimeType == other.runtimeType && host == other.host && port == other.port && protocol == other.protocol;
}
/// A single device confirmation over HTTP, fed into the store via
/// [RsDiscovery::add_device]: the device's register request was accepted by
/// our server, so it is known to be reachable at [RsDiscoveredDevice::host].
class RsDiscoveredDevice {
final String alias;
@@ -142,7 +163,7 @@ class RsDiscoveredDevice {
/// The port of the device's HTTP server.
final int port;
final ProtocolTypeV2 protocol;
final ProtocolType protocol;
/// Whether the device's download API is active.
final bool download;
@@ -186,3 +207,60 @@ class RsDiscoveredDevice {
protocol == other.protocol &&
download == other.download;
}
/// The merged stored state of a discovered device: one entry per fingerprint,
/// carrying every address the device was confirmed on. A multi-homed device
/// that is reachable over several network interfaces is still one
/// [RsStoredDevice].
///
/// Emitted on [RsDiscovery::listen] for every confirmation (answered
/// announcements, scan results and devices fed in via
/// [RsDiscovery::add_device]), so a device re-appears — with its channels
/// accumulated so far — whenever it re-announces itself or is re-discovered.
class RsStoredDevice {
final String alias;
/// Protocol version (major.minor) implemented by the device.
final String version;
final String? deviceModel;
final DeviceType? deviceType;
/// Fingerprint identifying the device; devices are deduplicated by it.
final String fingerprint;
/// Whether the device's download API is active.
final bool download;
/// Every address the device was confirmed on, best first (available
/// before not-reachable, IPv6 before IPv4, most recently confirmed
/// first). Never empty: a device only enters the store through a
/// confirmation.
final List<RsDeviceChannel> channels;
const RsStoredDevice({
required this.alias,
required this.version,
this.deviceModel,
this.deviceType,
required this.fingerprint,
required this.download,
required this.channels,
});
@override
int get hashCode =>
alias.hashCode ^ version.hashCode ^ deviceModel.hashCode ^ deviceType.hashCode ^ fingerprint.hashCode ^ download.hashCode ^ channels.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is RsStoredDevice &&
runtimeType == other.runtimeType &&
alias == other.alias &&
version == other.version &&
deviceModel == other.deviceModel &&
deviceType == other.deviceType &&
fingerprint == other.fingerprint &&
download == other.download &&
channels == other.channels;
}
@@ -112,11 +112,6 @@ abstract class RsHttpServer implements RustOpaqueInterface {
Future<void> stop();
}
enum ProtocolTypeV2 {
http,
https,
}
class RegisterDtoV2 {
final String alias;
final String version;
@@ -124,7 +119,7 @@ class RegisterDtoV2 {
final DeviceType? deviceType;
final String fingerprint;
final int port;
final ProtocolTypeV2 protocol;
final ProtocolType protocol;
final bool download;
const RegisterDtoV2({
@@ -117,14 +117,14 @@ abstract class RustLibApi extends BaseApi {
Future<void> crateApiDiscoveryRsDiscoveryAnnounce({required RsDiscovery that});
Future<RsDiscoveredDevice?> crateApiDiscoveryRsDiscoveryDiscover({
Future<RsStoredDevice?> crateApiDiscoveryRsDiscoveryDiscover({
required RsDiscovery that,
required String host,
required int port,
required ProtocolTypeV2 protocol,
required ProtocolType protocol,
});
Stream<RsDiscoveredDevice> crateApiDiscoveryRsDiscoveryListen({required RsDiscovery that});
Stream<RsStoredDevice> crateApiDiscoveryRsDiscoveryListen({required RsDiscovery that});
Future<String?> crateApiDiscoveryRsDiscoveryMulticastError({required RsDiscovery that});
@@ -132,7 +132,7 @@ abstract class RustLibApi extends BaseApi {
required RsDiscovery that,
required String interfaceIp,
required int port,
required ProtocolTypeV2 protocol,
required ProtocolType protocol,
});
Future<void> crateApiDiscoveryRsDiscoverySetAnswerAnnouncements({required RsDiscovery that, required bool answer});
@@ -286,7 +286,7 @@ abstract class RustLibApi extends BaseApi {
String? deviceModel,
DeviceType? deviceType,
required String fingerprint,
required ProtocolTypeV2 protocol,
required ProtocolType protocol,
required bool download,
required String certPem,
required String privateKeyPem,
@@ -613,11 +613,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
@override
Future<RsDiscoveredDevice?> crateApiDiscoveryRsDiscoveryDiscover({
Future<RsStoredDevice?> crateApiDiscoveryRsDiscoveryDiscover({
required RsDiscovery that,
required String host,
required int port,
required ProtocolTypeV2 protocol,
required ProtocolType protocol,
}) {
return handler.executeNormal(
NormalTask(
@@ -626,11 +626,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRsDiscovery(that, serializer);
sse_encode_String(host, serializer);
sse_encode_u_16(port, serializer);
sse_encode_protocol_type_v_2(protocol, serializer);
sse_encode_protocol_type(protocol, serializer);
pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 9, port: port_);
},
codec: SseCodec(
decodeSuccessData: sse_decode_opt_box_autoadd_rs_discovered_device,
decodeSuccessData: sse_decode_opt_box_autoadd_rs_stored_device,
decodeErrorData: null,
),
constMeta: kCrateApiDiscoveryRsDiscoveryDiscoverConstMeta,
@@ -646,15 +646,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
@override
Stream<RsDiscoveredDevice> crateApiDiscoveryRsDiscoveryListen({required RsDiscovery that}) {
final sink = RustStreamSink<RsDiscoveredDevice>();
Stream<RsStoredDevice> crateApiDiscoveryRsDiscoveryListen({required RsDiscovery that}) {
final sink = RustStreamSink<RsStoredDevice>();
unawaited(
handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRsDiscovery(that, serializer);
sse_encode_StreamSink_rs_discovered_device_Sse(sink, serializer);
sse_encode_StreamSink_rs_stored_device_Sse(sink, serializer);
pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 10, port: port_);
},
codec: SseCodec(
@@ -705,7 +705,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
required RsDiscovery that,
required String interfaceIp,
required int port,
required ProtocolTypeV2 protocol,
required ProtocolType protocol,
}) {
return handler.executeNormal(
NormalTask(
@@ -714,7 +714,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRsDiscovery(that, serializer);
sse_encode_String(interfaceIp, serializer);
sse_encode_u_16(port, serializer);
sse_encode_protocol_type_v_2(protocol, serializer);
sse_encode_protocol_type(protocol, serializer);
pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 12, port: port_);
},
codec: SseCodec(
@@ -1961,7 +1961,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
String? deviceModel,
DeviceType? deviceType,
required String fingerprint,
required ProtocolTypeV2 protocol,
required ProtocolType protocol,
required bool download,
required String certPem,
required String privateKeyPem,
@@ -1980,7 +1980,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_opt_String(deviceModel, serializer);
sse_encode_opt_box_autoadd_device_type(deviceType, serializer);
sse_encode_String(fingerprint, serializer);
sse_encode_protocol_type_v_2(protocol, serializer);
sse_encode_protocol_type(protocol, serializer);
sse_encode_bool(download, serializer);
sse_encode_String(certPem, serializer);
sse_encode_String(privateKeyPem, serializer);
@@ -2457,12 +2457,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
throw UnimplementedError();
}
@protected
RustStreamSink<RsDiscoveredDevice> dco_decode_StreamSink_rs_discovered_device_Sse(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
throw UnimplementedError();
}
@protected
RustStreamSink<RsHashFileEvent> dco_decode_StreamSink_rs_hash_file_event_Sse(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2475,6 +2469,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
throw UnimplementedError();
}
@protected
RustStreamSink<RsStoredDevice> dco_decode_StreamSink_rs_stored_device_Sse(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
throw UnimplementedError();
}
@protected
RustStreamSink<RTCFileError> dco_decode_StreamSink_rtc_file_error_Sse(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2603,6 +2603,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dco_decode_rs_discovered_device(raw);
}
@protected
RsStoredDevice dco_decode_box_autoadd_rs_stored_device(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_rs_stored_device(raw);
}
@protected
RTCSendFileResponse dco_decode_box_autoadd_rtc_send_file_response(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2777,6 +2783,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (raw as List<dynamic>).map(dco_decode_record_string_string).toList();
}
@protected
List<RsDeviceChannel> dco_decode_list_rs_device_channel(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return (raw as List<dynamic>).map(dco_decode_rs_device_channel).toList();
}
@protected
LsHttpClientVersion dco_decode_ls_http_client_version(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2835,9 +2847,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
@protected
RsDiscoveredDevice? dco_decode_opt_box_autoadd_rs_discovered_device(dynamic raw) {
RsStoredDevice? dco_decode_opt_box_autoadd_rs_stored_device(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return raw == null ? null : dco_decode_box_autoadd_rs_discovered_device(raw);
return raw == null ? null : dco_decode_box_autoadd_rs_stored_device(raw);
}
@protected
@@ -2933,12 +2945,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return ProtocolType.values[raw as int];
}
@protected
ProtocolTypeV2 dco_decode_protocol_type_v_2(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return ProtocolTypeV2.values[raw as int];
}
@protected
(Dart2RustStreamSink, Dart2RustStreamReceiver)
dco_decode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -3010,7 +3016,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
deviceType: dco_decode_opt_box_autoadd_device_type(arr[3]),
fingerprint: dco_decode_String(arr[4]),
port: dco_decode_u_16(arr[5]),
protocol: dco_decode_protocol_type_v_2(arr[6]),
protocol: dco_decode_protocol_type(arr[6]),
download: dco_decode_bool(arr[7]),
);
}
@@ -3041,6 +3047,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
}
@protected
RsDeviceChannel dco_decode_rs_device_channel(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 3) throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
return RsDeviceChannel(
host: dco_decode_String(arr[0]),
port: dco_decode_u_16(arr[1]),
protocol: dco_decode_protocol_type(arr[2]),
);
}
@protected
RsDiscoveredDevice dco_decode_rs_discovered_device(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -3054,7 +3072,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
fingerprint: dco_decode_String(arr[4]),
host: dco_decode_String(arr[5]),
port: dco_decode_u_16(arr[6]),
protocol: dco_decode_protocol_type_v_2(arr[7]),
protocol: dco_decode_protocol_type(arr[7]),
download: dco_decode_bool(arr[8]),
);
}
@@ -3164,6 +3182,22 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
RsStoredDevice dco_decode_rs_stored_device(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 7) throw Exception('unexpected arr length: expect 7 but see ${arr.length}');
return RsStoredDevice(
alias: dco_decode_String(arr[0]),
version: dco_decode_String(arr[1]),
deviceModel: dco_decode_opt_String(arr[2]),
deviceType: dco_decode_opt_box_autoadd_device_type(arr[3]),
fingerprint: dco_decode_String(arr[4]),
download: dco_decode_bool(arr[5]),
channels: dco_decode_list_rs_device_channel(arr[6]),
);
}
@protected
RTCFileError dco_decode_rtc_file_error(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -3638,12 +3672,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
throw UnimplementedError('Unreachable ()');
}
@protected
RustStreamSink<RsDiscoveredDevice> sse_decode_StreamSink_rs_discovered_device_Sse(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
throw UnimplementedError('Unreachable ()');
}
@protected
RustStreamSink<RsHashFileEvent> sse_decode_StreamSink_rs_hash_file_event_Sse(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3656,6 +3684,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
throw UnimplementedError('Unreachable ()');
}
@protected
RustStreamSink<RsStoredDevice> sse_decode_StreamSink_rs_stored_device_Sse(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
throw UnimplementedError('Unreachable ()');
}
@protected
RustStreamSink<RTCFileError> sse_decode_StreamSink_rtc_file_error_Sse(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3786,6 +3820,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (sse_decode_rs_discovered_device(deserializer));
}
@protected
RsStoredDevice sse_decode_box_autoadd_rs_stored_device(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_rs_stored_device(deserializer));
}
@protected
RTCSendFileResponse sse_decode_box_autoadd_rtc_send_file_response(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3983,6 +4023,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return ans_;
}
@protected
List<RsDeviceChannel> sse_decode_list_rs_device_channel(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var len_ = sse_decode_i_32(deserializer);
var ans_ = <RsDeviceChannel>[];
for (var idx_ = 0; idx_ < len_; ++idx_) {
ans_.add(sse_decode_rs_device_channel(deserializer));
}
return ans_;
}
@protected
LsHttpClientVersion sse_decode_ls_http_client_version(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -4082,11 +4134,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
@protected
RsDiscoveredDevice? sse_decode_opt_box_autoadd_rs_discovered_device(SseDeserializer deserializer) {
RsStoredDevice? sse_decode_opt_box_autoadd_rs_stored_device(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
if (sse_decode_bool(deserializer)) {
return (sse_decode_box_autoadd_rs_discovered_device(deserializer));
return (sse_decode_box_autoadd_rs_stored_device(deserializer));
} else {
return null;
}
@@ -4196,13 +4248,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return ProtocolType.values[inner];
}
@protected
ProtocolTypeV2 sse_decode_protocol_type_v_2(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var inner = sse_decode_i_32(deserializer);
return ProtocolTypeV2.values[inner];
}
@protected
(Dart2RustStreamSink, Dart2RustStreamReceiver)
sse_decode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -4262,7 +4307,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var var_deviceType = sse_decode_opt_box_autoadd_device_type(deserializer);
var var_fingerprint = sse_decode_String(deserializer);
var var_port = sse_decode_u_16(deserializer);
var var_protocol = sse_decode_protocol_type_v_2(deserializer);
var var_protocol = sse_decode_protocol_type(deserializer);
var var_download = sse_decode_bool(deserializer);
return RegisterDtoV2(
alias: var_alias,
@@ -4303,6 +4348,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return ResultWithPublicKeyRegisterResponseDto(publicKey: var_publicKey, body: var_body);
}
@protected
RsDeviceChannel sse_decode_rs_device_channel(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_host = sse_decode_String(deserializer);
var var_port = sse_decode_u_16(deserializer);
var var_protocol = sse_decode_protocol_type(deserializer);
return RsDeviceChannel(host: var_host, port: var_port, protocol: var_protocol);
}
@protected
RsDiscoveredDevice sse_decode_rs_discovered_device(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -4313,7 +4367,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var var_fingerprint = sse_decode_String(deserializer);
var var_host = sse_decode_String(deserializer);
var var_port = sse_decode_u_16(deserializer);
var var_protocol = sse_decode_protocol_type_v_2(deserializer);
var var_protocol = sse_decode_protocol_type(deserializer);
var var_download = sse_decode_bool(deserializer);
return RsDiscoveredDevice(
alias: var_alias,
@@ -4429,6 +4483,27 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
RsStoredDevice sse_decode_rs_stored_device(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_alias = sse_decode_String(deserializer);
var var_version = sse_decode_String(deserializer);
var var_deviceModel = sse_decode_opt_String(deserializer);
var var_deviceType = sse_decode_opt_box_autoadd_device_type(deserializer);
var var_fingerprint = sse_decode_String(deserializer);
var var_download = sse_decode_bool(deserializer);
var var_channels = sse_decode_list_rs_device_channel(deserializer);
return RsStoredDevice(
alias: var_alias,
version: var_version,
deviceModel: var_deviceModel,
deviceType: var_deviceType,
fingerprint: var_fingerprint,
download: var_download,
channels: var_channels,
);
}
@protected
RTCFileError sse_decode_rtc_file_error(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -4959,20 +5034,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
}
@protected
void sse_encode_StreamSink_rs_discovered_device_Sse(RustStreamSink<RsDiscoveredDevice> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(
self.setupAndSerialize(
codec: SseCodec(
decodeSuccessData: sse_decode_rs_discovered_device,
decodeErrorData: sse_decode_AnyhowException,
),
),
serializer,
);
}
@protected
void sse_encode_StreamSink_rs_hash_file_event_Sse(RustStreamSink<RsHashFileEvent> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -5001,6 +5062,20 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
}
@protected
void sse_encode_StreamSink_rs_stored_device_Sse(RustStreamSink<RsStoredDevice> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(
self.setupAndSerialize(
codec: SseCodec(
decodeSuccessData: sse_decode_rs_stored_device,
decodeErrorData: sse_decode_AnyhowException,
),
),
serializer,
);
}
@protected
void sse_encode_StreamSink_rtc_file_error_Sse(RustStreamSink<RTCFileError> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -5154,6 +5229,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_rs_discovered_device(self, serializer);
}
@protected
void sse_encode_box_autoadd_rs_stored_device(RsStoredDevice self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_rs_stored_device(self, serializer);
}
@protected
void sse_encode_box_autoadd_rtc_send_file_response(RTCSendFileResponse self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -5321,6 +5402,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
void sse_encode_list_rs_device_channel(List<RsDeviceChannel> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_i_32(self.length, serializer);
for (final item in self) {
sse_encode_rs_device_channel(item, serializer);
}
}
@protected
void sse_encode_ls_http_client_version(LsHttpClientVersion self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -5411,12 +5501,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
@protected
void sse_encode_opt_box_autoadd_rs_discovered_device(RsDiscoveredDevice? self, SseSerializer serializer) {
void sse_encode_opt_box_autoadd_rs_stored_device(RsStoredDevice? self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_bool(self != null, serializer);
if (self != null) {
sse_encode_box_autoadd_rs_discovered_device(self, serializer);
sse_encode_box_autoadd_rs_stored_device(self, serializer);
}
}
@@ -5513,12 +5603,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_i_32(self.index, serializer);
}
@protected
void sse_encode_protocol_type_v_2(ProtocolTypeV2 self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_i_32(self.index, serializer);
}
@protected
void
sse_encode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -5566,7 +5650,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_opt_box_autoadd_device_type(self.deviceType, serializer);
sse_encode_String(self.fingerprint, serializer);
sse_encode_u_16(self.port, serializer);
sse_encode_protocol_type_v_2(self.protocol, serializer);
sse_encode_protocol_type(self.protocol, serializer);
sse_encode_bool(self.download, serializer);
}
@@ -5588,6 +5672,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_register_response_dto(self.body, serializer);
}
@protected
void sse_encode_rs_device_channel(RsDeviceChannel self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.host, serializer);
sse_encode_u_16(self.port, serializer);
sse_encode_protocol_type(self.protocol, serializer);
}
@protected
void sse_encode_rs_discovered_device(RsDiscoveredDevice self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -5598,7 +5690,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_String(self.fingerprint, serializer);
sse_encode_String(self.host, serializer);
sse_encode_u_16(self.port, serializer);
sse_encode_protocol_type_v_2(self.protocol, serializer);
sse_encode_protocol_type(self.protocol, serializer);
sse_encode_bool(self.download, serializer);
}
@@ -5691,6 +5783,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
void sse_encode_rs_stored_device(RsStoredDevice self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.alias, serializer);
sse_encode_String(self.version, serializer);
sse_encode_opt_String(self.deviceModel, serializer);
sse_encode_opt_box_autoadd_device_type(self.deviceType, serializer);
sse_encode_String(self.fingerprint, serializer);
sse_encode_bool(self.download, serializer);
sse_encode_list_rs_device_channel(self.channels, serializer);
}
@protected
void sse_encode_rtc_file_error(RTCFileError self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -5995,12 +6099,12 @@ class RsDiscoveryImpl extends RustOpaque implements RsDiscovery {
/// The confirmed device is also emitted on [RsDiscovery::listen].
/// Returns `None` when the device did not answer or answered with this
/// device's own fingerprint (i.e. the device discovered itself).
Future<RsDiscoveredDevice?> discover({required String host, required int port, required ProtocolTypeV2 protocol}) =>
Future<RsStoredDevice?> discover({required String host, required int port, required ProtocolType protocol}) =>
RustLib.instance.api.crateApiDiscoveryRsDiscoveryDiscover(that: this, host: host, port: port, protocol: protocol);
/// Emits a [RsDiscoveredDevice] for every device confirmation until the
/// Emits a [RsStoredDevice] for every device confirmation until the
/// discovery is stopped. Can only be listened to once.
Stream<RsDiscoveredDevice> listen() => RustLib.instance.api.crateApiDiscoveryRsDiscoveryListen(
Stream<RsStoredDevice> listen() => RustLib.instance.api.crateApiDiscoveryRsDiscoveryListen(
that: this,
);
@@ -6018,7 +6122,7 @@ class RsDiscoveryImpl extends RustOpaque implements RsDiscovery {
/// this method returns once the whole scan has finished. At most one scan
/// runs per interface: a call for an address that is still being scanned
/// returns immediately.
Future<void> scanSubnet({required String interfaceIp, required int port, required ProtocolTypeV2 protocol}) =>
Future<void> scanSubnet({required String interfaceIp, required int port, required ProtocolType protocol}) =>
RustLib.instance.api.crateApiDiscoveryRsDiscoveryScanSubnet(that: this, interfaceIp: interfaceIp, port: port, protocol: protocol);
/// Sets whether announcements of other devices are answered with a
@@ -193,15 +193,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RustStreamSink<Uint8List> dco_decode_StreamSink_list_prim_u_8_strict_Sse(dynamic raw);
@protected
RustStreamSink<RsDiscoveredDevice> dco_decode_StreamSink_rs_discovered_device_Sse(dynamic raw);
@protected
RustStreamSink<RsHashFileEvent> dco_decode_StreamSink_rs_hash_file_event_Sse(dynamic raw);
@protected
RustStreamSink<RsServerEvent> dco_decode_StreamSink_rs_server_event_Sse(dynamic raw);
@protected
RustStreamSink<RsStoredDevice> dco_decode_StreamSink_rs_stored_device_Sse(dynamic raw);
@protected
RustStreamSink<RTCFileError> dco_decode_StreamSink_rtc_file_error_Sse(dynamic raw);
@@ -267,6 +267,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RsDiscoveredDevice dco_decode_box_autoadd_rs_discovered_device(dynamic raw);
@protected
RsStoredDevice dco_decode_box_autoadd_rs_stored_device(dynamic raw);
@protected
RTCSendFileResponse dco_decode_box_autoadd_rtc_send_file_response(dynamic raw);
@@ -333,6 +336,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
List<(String, String)> dco_decode_list_record_string_string(dynamic raw);
@protected
List<RsDeviceChannel> dco_decode_list_rs_device_channel(dynamic raw);
@protected
LsHttpClientVersion dco_decode_ls_http_client_version(dynamic raw);
@@ -362,7 +368,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
PrepareUploadResponseDto? dco_decode_opt_box_autoadd_prepare_upload_response_dto(dynamic raw);
@protected
RsDiscoveredDevice? dco_decode_opt_box_autoadd_rs_discovered_device(dynamic raw);
RsStoredDevice? dco_decode_opt_box_autoadd_rs_stored_device(dynamic raw);
@protected
TlsConfig? dco_decode_opt_box_autoadd_tls_config(dynamic raw);
@@ -397,9 +403,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
ProtocolType dco_decode_protocol_type(dynamic raw);
@protected
ProtocolTypeV2 dco_decode_protocol_type_v_2(dynamic raw);
@protected
(Dart2RustStreamSink, Dart2RustStreamReceiver)
dco_decode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -424,6 +427,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
ResultWithPublicKeyRegisterResponseDto dco_decode_result_with_public_key_register_response_dto(dynamic raw);
@protected
RsDeviceChannel dco_decode_rs_device_channel(dynamic raw);
@protected
RsDiscoveredDevice dco_decode_rs_discovered_device(dynamic raw);
@@ -436,6 +442,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RsServerEvent dco_decode_rs_server_event(dynamic raw);
@protected
RsStoredDevice dco_decode_rs_stored_device(dynamic raw);
@protected
RTCFileError dco_decode_rtc_file_error(dynamic raw);
@@ -633,15 +642,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RustStreamSink<Uint8List> sse_decode_StreamSink_list_prim_u_8_strict_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RsDiscoveredDevice> sse_decode_StreamSink_rs_discovered_device_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RsHashFileEvent> sse_decode_StreamSink_rs_hash_file_event_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RsServerEvent> sse_decode_StreamSink_rs_server_event_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RsStoredDevice> sse_decode_StreamSink_rs_stored_device_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RTCFileError> sse_decode_StreamSink_rtc_file_error_Sse(SseDeserializer deserializer);
@@ -707,6 +716,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RsDiscoveredDevice sse_decode_box_autoadd_rs_discovered_device(SseDeserializer deserializer);
@protected
RsStoredDevice sse_decode_box_autoadd_rs_stored_device(SseDeserializer deserializer);
@protected
RTCSendFileResponse sse_decode_box_autoadd_rtc_send_file_response(SseDeserializer deserializer);
@@ -773,6 +785,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
List<(String, String)> sse_decode_list_record_string_string(SseDeserializer deserializer);
@protected
List<RsDeviceChannel> sse_decode_list_rs_device_channel(SseDeserializer deserializer);
@protected
LsHttpClientVersion sse_decode_ls_http_client_version(SseDeserializer deserializer);
@@ -804,7 +819,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
PrepareUploadResponseDto? sse_decode_opt_box_autoadd_prepare_upload_response_dto(SseDeserializer deserializer);
@protected
RsDiscoveredDevice? sse_decode_opt_box_autoadd_rs_discovered_device(SseDeserializer deserializer);
RsStoredDevice? sse_decode_opt_box_autoadd_rs_stored_device(SseDeserializer deserializer);
@protected
TlsConfig? sse_decode_opt_box_autoadd_tls_config(SseDeserializer deserializer);
@@ -839,9 +854,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
ProtocolType sse_decode_protocol_type(SseDeserializer deserializer);
@protected
ProtocolTypeV2 sse_decode_protocol_type_v_2(SseDeserializer deserializer);
@protected
(Dart2RustStreamSink, Dart2RustStreamReceiver)
sse_decode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -866,6 +878,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
ResultWithPublicKeyRegisterResponseDto sse_decode_result_with_public_key_register_response_dto(SseDeserializer deserializer);
@protected
RsDeviceChannel sse_decode_rs_device_channel(SseDeserializer deserializer);
@protected
RsDiscoveredDevice sse_decode_rs_discovered_device(SseDeserializer deserializer);
@@ -878,6 +893,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RsServerEvent sse_decode_rs_server_event(SseDeserializer deserializer);
@protected
RsStoredDevice sse_decode_rs_stored_device(SseDeserializer deserializer);
@protected
RTCFileError sse_decode_rtc_file_error(SseDeserializer deserializer);
@@ -1119,15 +1137,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_StreamSink_list_prim_u_8_strict_Sse(RustStreamSink<Uint8List> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rs_discovered_device_Sse(RustStreamSink<RsDiscoveredDevice> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rs_hash_file_event_Sse(RustStreamSink<RsHashFileEvent> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rs_server_event_Sse(RustStreamSink<RsServerEvent> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rs_stored_device_Sse(RustStreamSink<RsStoredDevice> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rtc_file_error_Sse(RustStreamSink<RTCFileError> self, SseSerializer serializer);
@@ -1194,6 +1212,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_box_autoadd_rs_discovered_device(RsDiscoveredDevice self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_rs_stored_device(RsStoredDevice self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_rtc_send_file_response(RTCSendFileResponse self, SseSerializer serializer);
@@ -1260,6 +1281,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_list_record_string_string(List<(String, String)> self, SseSerializer serializer);
@protected
void sse_encode_list_rs_device_channel(List<RsDeviceChannel> self, SseSerializer serializer);
@protected
void sse_encode_ls_http_client_version(LsHttpClientVersion self, SseSerializer serializer);
@@ -1291,7 +1315,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
void sse_encode_opt_box_autoadd_prepare_upload_response_dto(PrepareUploadResponseDto? self, SseSerializer serializer);
@protected
void sse_encode_opt_box_autoadd_rs_discovered_device(RsDiscoveredDevice? self, SseSerializer serializer);
void sse_encode_opt_box_autoadd_rs_stored_device(RsStoredDevice? self, SseSerializer serializer);
@protected
void sse_encode_opt_box_autoadd_tls_config(TlsConfig? self, SseSerializer serializer);
@@ -1326,9 +1350,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_protocol_type(ProtocolType self, SseSerializer serializer);
@protected
void sse_encode_protocol_type_v_2(ProtocolTypeV2 self, SseSerializer serializer);
@protected
void
sse_encode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -1354,6 +1375,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_result_with_public_key_register_response_dto(ResultWithPublicKeyRegisterResponseDto self, SseSerializer serializer);
@protected
void sse_encode_rs_device_channel(RsDeviceChannel self, SseSerializer serializer);
@protected
void sse_encode_rs_discovered_device(RsDiscoveredDevice self, SseSerializer serializer);
@@ -1366,6 +1390,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_rs_server_event(RsServerEvent self, SseSerializer serializer);
@protected
void sse_encode_rs_stored_device(RsStoredDevice self, SseSerializer serializer);
@protected
void sse_encode_rtc_file_error(RTCFileError self, SseSerializer serializer);
@@ -195,15 +195,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RustStreamSink<Uint8List> dco_decode_StreamSink_list_prim_u_8_strict_Sse(dynamic raw);
@protected
RustStreamSink<RsDiscoveredDevice> dco_decode_StreamSink_rs_discovered_device_Sse(dynamic raw);
@protected
RustStreamSink<RsHashFileEvent> dco_decode_StreamSink_rs_hash_file_event_Sse(dynamic raw);
@protected
RustStreamSink<RsServerEvent> dco_decode_StreamSink_rs_server_event_Sse(dynamic raw);
@protected
RustStreamSink<RsStoredDevice> dco_decode_StreamSink_rs_stored_device_Sse(dynamic raw);
@protected
RustStreamSink<RTCFileError> dco_decode_StreamSink_rtc_file_error_Sse(dynamic raw);
@@ -269,6 +269,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RsDiscoveredDevice dco_decode_box_autoadd_rs_discovered_device(dynamic raw);
@protected
RsStoredDevice dco_decode_box_autoadd_rs_stored_device(dynamic raw);
@protected
RTCSendFileResponse dco_decode_box_autoadd_rtc_send_file_response(dynamic raw);
@@ -335,6 +338,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
List<(String, String)> dco_decode_list_record_string_string(dynamic raw);
@protected
List<RsDeviceChannel> dco_decode_list_rs_device_channel(dynamic raw);
@protected
LsHttpClientVersion dco_decode_ls_http_client_version(dynamic raw);
@@ -364,7 +370,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
PrepareUploadResponseDto? dco_decode_opt_box_autoadd_prepare_upload_response_dto(dynamic raw);
@protected
RsDiscoveredDevice? dco_decode_opt_box_autoadd_rs_discovered_device(dynamic raw);
RsStoredDevice? dco_decode_opt_box_autoadd_rs_stored_device(dynamic raw);
@protected
TlsConfig? dco_decode_opt_box_autoadd_tls_config(dynamic raw);
@@ -399,9 +405,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
ProtocolType dco_decode_protocol_type(dynamic raw);
@protected
ProtocolTypeV2 dco_decode_protocol_type_v_2(dynamic raw);
@protected
(Dart2RustStreamSink, Dart2RustStreamReceiver)
dco_decode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -426,6 +429,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
ResultWithPublicKeyRegisterResponseDto dco_decode_result_with_public_key_register_response_dto(dynamic raw);
@protected
RsDeviceChannel dco_decode_rs_device_channel(dynamic raw);
@protected
RsDiscoveredDevice dco_decode_rs_discovered_device(dynamic raw);
@@ -438,6 +444,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RsServerEvent dco_decode_rs_server_event(dynamic raw);
@protected
RsStoredDevice dco_decode_rs_stored_device(dynamic raw);
@protected
RTCFileError dco_decode_rtc_file_error(dynamic raw);
@@ -635,15 +644,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RustStreamSink<Uint8List> sse_decode_StreamSink_list_prim_u_8_strict_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RsDiscoveredDevice> sse_decode_StreamSink_rs_discovered_device_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RsHashFileEvent> sse_decode_StreamSink_rs_hash_file_event_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RsServerEvent> sse_decode_StreamSink_rs_server_event_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RsStoredDevice> sse_decode_StreamSink_rs_stored_device_Sse(SseDeserializer deserializer);
@protected
RustStreamSink<RTCFileError> sse_decode_StreamSink_rtc_file_error_Sse(SseDeserializer deserializer);
@@ -709,6 +718,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RsDiscoveredDevice sse_decode_box_autoadd_rs_discovered_device(SseDeserializer deserializer);
@protected
RsStoredDevice sse_decode_box_autoadd_rs_stored_device(SseDeserializer deserializer);
@protected
RTCSendFileResponse sse_decode_box_autoadd_rtc_send_file_response(SseDeserializer deserializer);
@@ -775,6 +787,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
List<(String, String)> sse_decode_list_record_string_string(SseDeserializer deserializer);
@protected
List<RsDeviceChannel> sse_decode_list_rs_device_channel(SseDeserializer deserializer);
@protected
LsHttpClientVersion sse_decode_ls_http_client_version(SseDeserializer deserializer);
@@ -806,7 +821,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
PrepareUploadResponseDto? sse_decode_opt_box_autoadd_prepare_upload_response_dto(SseDeserializer deserializer);
@protected
RsDiscoveredDevice? sse_decode_opt_box_autoadd_rs_discovered_device(SseDeserializer deserializer);
RsStoredDevice? sse_decode_opt_box_autoadd_rs_stored_device(SseDeserializer deserializer);
@protected
TlsConfig? sse_decode_opt_box_autoadd_tls_config(SseDeserializer deserializer);
@@ -841,9 +856,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
ProtocolType sse_decode_protocol_type(SseDeserializer deserializer);
@protected
ProtocolTypeV2 sse_decode_protocol_type_v_2(SseDeserializer deserializer);
@protected
(Dart2RustStreamSink, Dart2RustStreamReceiver)
sse_decode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -868,6 +880,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
ResultWithPublicKeyRegisterResponseDto sse_decode_result_with_public_key_register_response_dto(SseDeserializer deserializer);
@protected
RsDeviceChannel sse_decode_rs_device_channel(SseDeserializer deserializer);
@protected
RsDiscoveredDevice sse_decode_rs_discovered_device(SseDeserializer deserializer);
@@ -880,6 +895,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RsServerEvent sse_decode_rs_server_event(SseDeserializer deserializer);
@protected
RsStoredDevice sse_decode_rs_stored_device(SseDeserializer deserializer);
@protected
RTCFileError sse_decode_rtc_file_error(SseDeserializer deserializer);
@@ -1121,15 +1139,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_StreamSink_list_prim_u_8_strict_Sse(RustStreamSink<Uint8List> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rs_discovered_device_Sse(RustStreamSink<RsDiscoveredDevice> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rs_hash_file_event_Sse(RustStreamSink<RsHashFileEvent> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rs_server_event_Sse(RustStreamSink<RsServerEvent> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rs_stored_device_Sse(RustStreamSink<RsStoredDevice> self, SseSerializer serializer);
@protected
void sse_encode_StreamSink_rtc_file_error_Sse(RustStreamSink<RTCFileError> self, SseSerializer serializer);
@@ -1196,6 +1214,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_box_autoadd_rs_discovered_device(RsDiscoveredDevice self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_rs_stored_device(RsStoredDevice self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_rtc_send_file_response(RTCSendFileResponse self, SseSerializer serializer);
@@ -1262,6 +1283,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_list_record_string_string(List<(String, String)> self, SseSerializer serializer);
@protected
void sse_encode_list_rs_device_channel(List<RsDeviceChannel> self, SseSerializer serializer);
@protected
void sse_encode_ls_http_client_version(LsHttpClientVersion self, SseSerializer serializer);
@@ -1293,7 +1317,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
void sse_encode_opt_box_autoadd_prepare_upload_response_dto(PrepareUploadResponseDto? self, SseSerializer serializer);
@protected
void sse_encode_opt_box_autoadd_rs_discovered_device(RsDiscoveredDevice? self, SseSerializer serializer);
void sse_encode_opt_box_autoadd_rs_stored_device(RsStoredDevice? self, SseSerializer serializer);
@protected
void sse_encode_opt_box_autoadd_tls_config(TlsConfig? self, SseSerializer serializer);
@@ -1328,9 +1352,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_protocol_type(ProtocolType self, SseSerializer serializer);
@protected
void sse_encode_protocol_type_v_2(ProtocolTypeV2 self, SseSerializer serializer);
@protected
void
sse_encode_record_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_sink_auto_owned_rust_opaque_flutter_rust_bridgefor_generated_rust_auto_opaque_inner_dart_2_rust_stream_receiver(
@@ -1356,6 +1377,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_result_with_public_key_register_response_dto(ResultWithPublicKeyRegisterResponseDto self, SseSerializer serializer);
@protected
void sse_encode_rs_device_channel(RsDeviceChannel self, SseSerializer serializer);
@protected
void sse_encode_rs_discovered_device(RsDiscoveredDevice self, SseSerializer serializer);
@@ -1368,6 +1392,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_rs_server_event(RsServerEvent self, SseSerializer serializer);
@protected
void sse_encode_rs_stored_device(RsStoredDevice self, SseSerializer serializer);
@protected
void sse_encode_rtc_file_error(RTCFileError self, SseSerializer serializer);
@@ -2,9 +2,8 @@ import 'dart:async';
import 'package:localsend_isolates/constants.dart';
import 'package:localsend_isolates/model/device.dart';
import 'package:localsend_isolates/model/dto/multicast_dto.dart';
import 'package:localsend_isolates/rust/api/discovery.dart';
import 'package:localsend_isolates/rust/api/server.dart' show ProtocolTypeV2;
import 'package:localsend_isolates/rust/api/model.dart' as rust_model;
import 'package:localsend_isolates/src/isolate/child/sync_provider.dart';
import 'package:localsend_isolates/util/rust.dart';
import 'package:logging/logging.dart';
@@ -68,7 +67,7 @@ class DiscoveryService {
deviceModel: syncState.deviceInfo.deviceModel,
deviceType: syncState.deviceInfo.deviceType.toRust(),
fingerprint: syncState.securityContext.certificateHash,
protocol: syncState.protocol == ProtocolType.https ? ProtocolTypeV2.https : ProtocolTypeV2.http,
protocol: syncState.protocol.toRust(),
download: syncState.download,
certPem: syncState.securityContext.certificate,
privateKeyPem: syncState.securityContext.privateKey,
@@ -145,7 +144,7 @@ class DiscoveryService {
await discovery.scanSubnet(
interfaceIp: networkInterface,
port: port,
protocol: https ? ProtocolTypeV2.https : ProtocolTypeV2.http,
protocol: https ? rust_model.ProtocolType.https : rust_model.ProtocolType.http,
);
}
@@ -159,7 +158,7 @@ class DiscoveryService {
return;
}
final protocol = https ? ProtocolTypeV2.https : ProtocolTypeV2.http;
final protocol = https ? rust_model.ProtocolType.https : rust_model.ProtocolType.http;
await Future.wait([
for (final (host, port) in devices) discovery.discover(host: host, port: port, protocol: protocol),
]);
+10 -7
View File
@@ -129,20 +129,23 @@ extension RustFileDtoExt on rust_model.FileDto {
}
}
extension RsDiscoveredDeviceExt on rust_discovery.RsDiscoveredDevice {
extension RsStoredDeviceExt on rust_discovery.RsStoredDevice {
/// Maps the merged stored state to a [Device]: the best channel becomes the
/// dialed address, every channel is kept as a [HttpDiscovery] method.
Device toDevice() {
final best = channels.first;
return Device(
signalingId: null,
ip: host,
ip: best.host,
version: version,
port: port,
https: protocol == rust_server.ProtocolTypeV2.https,
port: best.port,
https: best.protocol == rust_model.ProtocolType.https,
fingerprint: fingerprint,
alias: alias,
deviceModel: deviceModel,
deviceType: deviceType?.toDart() ?? DeviceType.desktop,
download: download,
discoveryMethods: {HttpDiscovery(ip: host)},
discoveryMethods: {for (final channel in channels) HttpDiscovery(ip: channel.host)},
);
}
}
@@ -157,7 +160,7 @@ extension DeviceToRsDiscoveredDeviceExt on Device {
fingerprint: fingerprint,
host: ip,
port: port,
protocol: https ? rust_server.ProtocolTypeV2.https : rust_server.ProtocolTypeV2.http,
protocol: https ? rust_model.ProtocolType.https : rust_model.ProtocolType.http,
download: download,
);
}
@@ -170,7 +173,7 @@ extension RegisterDtoV2Ext on rust_server.RegisterDtoV2 {
ip: ip,
version: version,
port: port,
https: protocol == rust_server.ProtocolTypeV2.https,
https: protocol == rust_model.ProtocolType.https,
fingerprint: fingerprint,
alias: alias,
deviceModel: deviceModel,
@@ -1,20 +1,16 @@
use crate::frb_generated::StreamSink;
use localsend::discovery::{
DeviceChannel, DeviceIdentity, DiscoveredDevice, DiscoveryConfig, DiscoveryEvent,
DiscoveryHandle, HttpChannel,
DiscoveryHandle, HttpChannel, StatefulDevice,
};
use localsend::http::dto_v2::ProtocolTypeV2;
use localsend::model::discovery::DeviceType;
use localsend::model::discovery::{DeviceType, ProtocolType};
use localsend::multicast::{DEFAULT_MULTICAST_GROUP_V6, InterfaceFilter, MulticastDevice};
use std::time::Duration;
use tokio::sync::{Mutex, mpsc, oneshot};
/// A device that was confirmed over HTTP by the discovery: it answered a
/// register request, or its register request was accepted by our server and
/// was fed back via [RsDiscovery::add_device].
///
/// Emitted on [RsDiscovery::listen] for every confirmation, so a device
/// re-appears whenever it re-announces itself or is re-discovered.
/// A single device confirmation over HTTP, fed into the store via
/// [RsDiscovery::add_device]: the device's register request was accepted by
/// our server, so it is known to be reachable at [RsDiscoveredDevice::host].
pub struct RsDiscoveredDevice {
pub alias: String,
@@ -36,12 +32,56 @@ pub struct RsDiscoveredDevice {
/// The port of the device's HTTP server.
pub port: u16,
pub protocol: ProtocolTypeV2,
pub protocol: ProtocolType,
/// Whether the device's download API is active.
pub download: bool,
}
/// An address a stored device was confirmed on and is dialed at.
pub struct RsDeviceChannel {
/// The host to dial: an IP address, or the scoped form `fe80::1%3` for
/// link-local IPv6 (the Rust HTTP client accepts both back as a host).
pub host: String,
/// The port of the device's HTTP server at this address.
pub port: u16,
pub protocol: ProtocolType,
}
/// The merged stored state of a discovered device: one entry per fingerprint,
/// carrying every address the device was confirmed on. A multi-homed device
/// that is reachable over several network interfaces is still one
/// [RsStoredDevice].
///
/// Emitted on [RsDiscovery::listen] for every confirmation (answered
/// announcements, scan results and devices fed in via
/// [RsDiscovery::add_device]), so a device re-appears — with its channels
/// accumulated so far — whenever it re-announces itself or is re-discovered.
pub struct RsStoredDevice {
pub alias: String,
/// Protocol version (major.minor) implemented by the device.
pub version: String,
pub device_model: Option<String>,
pub device_type: Option<DeviceType>,
/// Fingerprint identifying the device; devices are deduplicated by it.
pub fingerprint: String,
/// Whether the device's download API is active.
pub download: bool,
/// Every address the device was confirmed on, best first (available
/// before not-reachable, IPv6 before IPv4, most recently confirmed
/// first). Never empty: a device only enters the store through a
/// confirmation.
pub channels: Vec<RsDeviceChannel>,
}
pub struct RsDiscovery {
handle: DiscoveryHandle,
event_rx: Mutex<Option<mpsc::Receiver<DiscoveryEvent>>>,
@@ -77,7 +117,7 @@ pub async fn start_discovery(
device_model: Option<String>,
device_type: Option<DeviceType>,
fingerprint: String,
protocol: ProtocolTypeV2,
protocol: ProtocolType,
download: bool,
cert_pem: String,
private_key_pem: String,
@@ -129,9 +169,9 @@ pub async fn start_discovery(
}
impl RsDiscovery {
/// Emits a [RsDiscoveredDevice] for every device confirmation until the
/// Emits a [RsStoredDevice] for every device confirmation until the
/// discovery is stopped. Can only be listened to once.
pub async fn listen(&self, sink: StreamSink<RsDiscoveredDevice>) {
pub async fn listen(&self, sink: StreamSink<RsStoredDevice>) {
let Some(mut event_rx) = self.event_rx.lock().await.take() else {
let _ = sink.add_error(anyhow::anyhow!("Discovery events already listened to"));
return;
@@ -140,7 +180,11 @@ impl RsDiscovery {
while let Some(event) = event_rx.recv().await {
let (DiscoveryEvent::Discovered { device } | DiscoveryEvent::Updated { device }) =
event;
let _ = sink.add(rs_device(device));
// The store is updated before the event is emitted, so the merged
// state is at least as new as the confirmation.
if let Some(stored) = self.handle.device_by_fingerprint(&device.fingerprint) {
let _ = sink.add(rs_stored_device(stored));
}
}
}
@@ -183,10 +227,10 @@ impl RsDiscovery {
&self,
host: String,
port: u16,
protocol: ProtocolTypeV2,
) -> Option<RsDiscoveredDevice> {
protocol: ProtocolType,
) -> Option<RsStoredDevice> {
match self.handle.discover(&host, port, protocol).await {
Ok(found) => found.map(|found| rs_device(found.device)),
Ok(found) => found.map(rs_stored_device),
Err(err) => {
tracing::debug!("Could not discover {host}:{port}: {err:#}");
None
@@ -206,7 +250,7 @@ impl RsDiscovery {
&self,
interface_ip: String,
port: u16,
protocol: ProtocolTypeV2,
protocol: ProtocolType,
) -> anyhow::Result<()> {
let interface_ip = interface_ip
.parse()
@@ -246,19 +290,30 @@ impl RsDiscovery {
}
}
/// The stored device flattened for the Dart side; only the channel of the
/// current confirmation is carried.
fn rs_device(device: DiscoveredDevice) -> RsDiscoveredDevice {
let DeviceChannel::Http(http) = device.channel;
RsDiscoveredDevice {
/// The merged stored device flattened for the Dart side, its channels ranked
/// best first.
fn rs_stored_device(stored: StatefulDevice) -> RsStoredDevice {
let channels = stored
.get_ranked_channels()
.into_iter()
.map(|channel| {
let DeviceChannel::Http(http) = channel;
RsDeviceChannel {
host: http.host.clone(),
port: http.port,
protocol: http.protocol,
}
})
.collect();
let device = stored.device;
RsStoredDevice {
alias: device.alias,
version: device.version,
device_model: device.device_model,
device_type: device.device_type,
fingerprint: device.fingerprint,
host: http.host,
port: http.port,
protocol: http.protocol,
download: device.download,
channels,
}
}
@@ -4,9 +4,10 @@ use crate::frb_generated::StreamSink;
use flutter_rust_bridge::frb;
pub use localsend::http::client::{ClientError, LsHttpClientVersion};
pub use localsend::http::dto::{
PrepareUploadRequestDto, PrepareUploadResponseDto, PrepareUploadResult, ProtocolType,
PrepareUploadRequestDto, PrepareUploadResponseDto, PrepareUploadResult,
RegisterDto, RegisterResponseDto,
};
use localsend::model::discovery::ProtocolType;
use localsend::reqwest;
pub struct RsHttpClient {
@@ -1,9 +1,9 @@
use flutter_rust_bridge::frb;
pub use localsend::http::dto::{
PrepareUploadRequestDto, PrepareUploadResponseDto, ProtocolType, RegisterDto,
RegisterResponseDto,
PrepareUploadRequestDto, PrepareUploadResponseDto, RegisterDto, RegisterResponseDto,
};
pub use localsend::model::discovery::DeviceType;
pub use localsend::model::discovery::ProtocolType;
pub use localsend::model::transfer::{FileDto, FileMetadata};
use std::collections::HashMap;
@@ -1,6 +1,7 @@
use crate::frb_generated::StreamSink;
use flutter_rust_bridge::frb;
pub use localsend::http::dto_v2::{ProtocolTypeV2, RegisterDtoV2};
pub use localsend::http::dto_v2::RegisterDtoV2;
use localsend::model::discovery::ProtocolType;
use localsend::http::server::ServerConfigV2;
pub use localsend::http::server::TlsConfig;
use localsend::http::server::common::save::FileUploadTarget;
@@ -640,12 +641,6 @@ pub struct _TlsConfig {
pub private_key: String,
}
#[frb(mirror(ProtocolTypeV2))]
pub enum _ProtocolTypeV2 {
Http,
Https,
}
#[frb(mirror(RegisterDtoV2))]
pub struct _RegisterDtoV2 {
pub alias: String,
@@ -654,7 +649,7 @@ pub struct _RegisterDtoV2 {
pub device_type: Option<DeviceType>,
pub fingerprint: String,
pub port: u16,
pub protocol: ProtocolTypeV2,
pub protocol: ProtocolType,
pub download: bool,
}
@@ -555,7 +555,7 @@ fn wire__crate__api__discovery__RsDiscovery_discover_impl(
>>::sse_decode(&mut deserializer);
let api_host = <String>::sse_decode(&mut deserializer);
let api_port = <u16>::sse_decode(&mut deserializer);
let api_protocol = <crate::api::server::ProtocolTypeV2>::sse_decode(&mut deserializer);
let api_protocol = <crate::api::model::ProtocolType>::sse_decode(&mut deserializer);
deserializer.end();
move |context| async move {
transform_result_sse::<_, ()>(
@@ -620,7 +620,7 @@ fn wire__crate__api__discovery__RsDiscovery_listen_impl(
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<RsDiscovery>,
>>::sse_decode(&mut deserializer);
let api_sink = <StreamSink<
crate::api::discovery::RsDiscoveredDevice,
crate::api::discovery::RsStoredDevice,
flutter_rust_bridge::for_generated::SseCodec,
>>::sse_decode(&mut deserializer);
deserializer.end();
@@ -734,7 +734,7 @@ fn wire__crate__api__discovery__RsDiscovery_scan_subnet_impl(
>>::sse_decode(&mut deserializer);
let api_interface_ip = <String>::sse_decode(&mut deserializer);
let api_port = <u16>::sse_decode(&mut deserializer);
let api_protocol = <crate::api::server::ProtocolTypeV2>::sse_decode(&mut deserializer);
let api_protocol = <crate::api::model::ProtocolType>::sse_decode(&mut deserializer);
deserializer.end();
move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
@@ -3136,7 +3136,7 @@ fn wire__crate__api__discovery__start_discovery_impl(
let api_device_type =
<Option<crate::api::model::DeviceType>>::sse_decode(&mut deserializer);
let api_fingerprint = <String>::sse_decode(&mut deserializer);
let api_protocol = <crate::api::server::ProtocolTypeV2>::sse_decode(&mut deserializer);
let api_protocol = <crate::api::model::ProtocolType>::sse_decode(&mut deserializer);
let api_download = <bool>::sse_decode(&mut deserializer);
let api_cert_pem = <String>::sse_decode(&mut deserializer);
let api_private_key_pem = <String>::sse_decode(&mut deserializer);
@@ -3342,7 +3342,7 @@ const _: fn() = || {
let _: Option<crate::api::model::DeviceType> = RegisterDtoV2.device_type;
let _: String = RegisterDtoV2.fingerprint;
let _: u16 = RegisterDtoV2.port;
let _: crate::api::server::ProtocolTypeV2 = RegisterDtoV2.protocol;
let _: crate::api::model::ProtocolType = RegisterDtoV2.protocol;
let _: bool = RegisterDtoV2.download;
}
{
@@ -3783,19 +3783,6 @@ impl SseDecode for StreamSink<Vec<u8>, flutter_rust_bridge::for_generated::SseCo
}
}
impl SseDecode
for StreamSink<
crate::api::discovery::RsDiscoveredDevice,
flutter_rust_bridge::for_generated::SseCodec,
>
{
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut inner = <String>::sse_decode(deserializer);
return StreamSink::deserialize(inner);
}
}
impl SseDecode
for StreamSink<
crate::api::crypto::RsHashFileEvent,
@@ -3819,6 +3806,19 @@ impl SseDecode
}
}
impl SseDecode
for StreamSink<
crate::api::discovery::RsStoredDevice,
flutter_rust_bridge::for_generated::SseCodec,
>
{
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut inner = <String>::sse_decode(deserializer);
return StreamSink::deserialize(inner);
}
}
impl SseDecode
for StreamSink<crate::api::webrtc::RTCFileError, flutter_rust_bridge::for_generated::SseCodec>
{
@@ -4081,6 +4081,20 @@ impl SseDecode for Vec<(String, String)> {
}
}
impl SseDecode for Vec<crate::api::discovery::RsDeviceChannel> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut len_ = <i32>::sse_decode(deserializer);
let mut ans_ = Vec::with_capacity(len_ as usize);
for idx_ in 0..len_ {
ans_.push(<crate::api::discovery::RsDeviceChannel>::sse_decode(
deserializer,
));
}
return ans_;
}
}
impl SseDecode for crate::api::http::LsHttpClientVersion {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -4185,11 +4199,11 @@ impl SseDecode for Option<crate::api::model::PrepareUploadResponseDto> {
}
}
impl SseDecode for Option<crate::api::discovery::RsDiscoveredDevice> {
impl SseDecode for Option<crate::api::discovery::RsStoredDevice> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
if (<bool>::sse_decode(deserializer)) {
return Some(<crate::api::discovery::RsDiscoveredDevice>::sse_decode(
return Some(<crate::api::discovery::RsStoredDevice>::sse_decode(
deserializer,
));
} else {
@@ -4335,18 +4349,6 @@ impl SseDecode for crate::api::model::ProtocolType {
}
}
impl SseDecode for crate::api::server::ProtocolTypeV2 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut inner = <i32>::sse_decode(deserializer);
return match inner {
0 => crate::api::server::ProtocolTypeV2::Http,
1 => crate::api::server::ProtocolTypeV2::Https,
_ => unreachable!("Invalid variant for ProtocolTypeV2: {}", inner),
};
}
}
impl SseDecode for (Dart2RustStreamSink, Dart2RustStreamReceiver) {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -4407,7 +4409,7 @@ impl SseDecode for crate::api::server::RegisterDtoV2 {
let mut var_deviceType = <Option<crate::api::model::DeviceType>>::sse_decode(deserializer);
let mut var_fingerprint = <String>::sse_decode(deserializer);
let mut var_port = <u16>::sse_decode(deserializer);
let mut var_protocol = <crate::api::server::ProtocolTypeV2>::sse_decode(deserializer);
let mut var_protocol = <crate::api::model::ProtocolType>::sse_decode(deserializer);
let mut var_download = <bool>::sse_decode(deserializer);
return crate::api::server::RegisterDtoV2 {
alias: var_alias,
@@ -4454,6 +4456,20 @@ impl SseDecode for crate::api::http::ResultWithPublicKeyRegisterResponseDto {
}
}
impl SseDecode for crate::api::discovery::RsDeviceChannel {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_host = <String>::sse_decode(deserializer);
let mut var_port = <u16>::sse_decode(deserializer);
let mut var_protocol = <crate::api::model::ProtocolType>::sse_decode(deserializer);
return crate::api::discovery::RsDeviceChannel {
host: var_host,
port: var_port,
protocol: var_protocol,
};
}
}
impl SseDecode for crate::api::discovery::RsDiscoveredDevice {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -4464,7 +4480,7 @@ impl SseDecode for crate::api::discovery::RsDiscoveredDevice {
let mut var_fingerprint = <String>::sse_decode(deserializer);
let mut var_host = <String>::sse_decode(deserializer);
let mut var_port = <u16>::sse_decode(deserializer);
let mut var_protocol = <crate::api::server::ProtocolTypeV2>::sse_decode(deserializer);
let mut var_protocol = <crate::api::model::ProtocolType>::sse_decode(deserializer);
let mut var_download = <bool>::sse_decode(deserializer);
return crate::api::discovery::RsDiscoveredDevice {
alias: var_alias,
@@ -4630,6 +4646,29 @@ impl SseDecode for crate::api::server::RsServerEvent {
}
}
impl SseDecode for crate::api::discovery::RsStoredDevice {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_alias = <String>::sse_decode(deserializer);
let mut var_version = <String>::sse_decode(deserializer);
let mut var_deviceModel = <Option<String>>::sse_decode(deserializer);
let mut var_deviceType = <Option<crate::api::model::DeviceType>>::sse_decode(deserializer);
let mut var_fingerprint = <String>::sse_decode(deserializer);
let mut var_download = <bool>::sse_decode(deserializer);
let mut var_channels =
<Vec<crate::api::discovery::RsDeviceChannel>>::sse_decode(deserializer);
return crate::api::discovery::RsStoredDevice {
alias: var_alias,
version: var_version,
device_model: var_deviceModel,
device_type: var_deviceType,
fingerprint: var_fingerprint,
download: var_download,
channels: var_channels,
};
}
}
impl SseDecode for crate::api::webrtc::RTCFileError {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -5626,27 +5665,6 @@ impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<crate::api::model::ProtocolTyp
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for FrbWrapper<crate::api::server::ProtocolTypeV2> {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
match self.0 {
crate::api::server::ProtocolTypeV2::Http => 0.into_dart(),
crate::api::server::ProtocolTypeV2::Https => 1.into_dart(),
_ => unreachable!(),
}
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for FrbWrapper<crate::api::server::ProtocolTypeV2>
{
}
impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<crate::api::server::ProtocolTypeV2>>
for crate::api::server::ProtocolTypeV2
{
fn into_into_dart(self) -> FrbWrapper<crate::api::server::ProtocolTypeV2> {
self.into()
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for FrbWrapper<crate::api::model::RegisterDto> {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
@@ -5747,6 +5765,28 @@ impl flutter_rust_bridge::IntoIntoDart<crate::api::http::ResultWithPublicKeyRegi
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::api::discovery::RsDeviceChannel {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.host.into_into_dart().into_dart(),
self.port.into_into_dart().into_dart(),
self.protocol.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::api::discovery::RsDeviceChannel
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::api::discovery::RsDeviceChannel>
for crate::api::discovery::RsDeviceChannel
{
fn into_into_dart(self) -> crate::api::discovery::RsDeviceChannel {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::api::discovery::RsDiscoveredDevice {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
@@ -5934,6 +5974,32 @@ impl flutter_rust_bridge::IntoIntoDart<crate::api::server::RsServerEvent>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::api::discovery::RsStoredDevice {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.alias.into_into_dart().into_dart(),
self.version.into_into_dart().into_dart(),
self.device_model.into_into_dart().into_dart(),
self.device_type.into_into_dart().into_dart(),
self.fingerprint.into_into_dart().into_dart(),
self.download.into_into_dart().into_dart(),
self.channels.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::api::discovery::RsStoredDevice
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::api::discovery::RsStoredDevice>
for crate::api::discovery::RsStoredDevice
{
fn into_into_dart(self) -> crate::api::discovery::RsStoredDevice {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for FrbWrapper<crate::api::webrtc::RTCFileError> {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
@@ -6465,18 +6531,6 @@ impl SseEncode for StreamSink<Vec<u8>, flutter_rust_bridge::for_generated::SseCo
}
}
impl SseEncode
for StreamSink<
crate::api::discovery::RsDiscoveredDevice,
flutter_rust_bridge::for_generated::SseCodec,
>
{
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
unimplemented!("")
}
}
impl SseEncode
for StreamSink<
crate::api::crypto::RsHashFileEvent,
@@ -6498,6 +6552,18 @@ impl SseEncode
}
}
impl SseEncode
for StreamSink<
crate::api::discovery::RsStoredDevice,
flutter_rust_bridge::for_generated::SseCodec,
>
{
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
unimplemented!("")
}
}
impl SseEncode
for StreamSink<crate::api::webrtc::RTCFileError, flutter_rust_bridge::for_generated::SseCodec>
{
@@ -6712,6 +6778,16 @@ impl SseEncode for Vec<(String, String)> {
}
}
impl SseEncode for Vec<crate::api::discovery::RsDeviceChannel> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<i32>::sse_encode(self.len() as _, serializer);
for item in self {
<crate::api::discovery::RsDeviceChannel>::sse_encode(item, serializer);
}
}
}
impl SseEncode for crate::api::http::LsHttpClientVersion {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -6808,12 +6884,12 @@ impl SseEncode for Option<crate::api::model::PrepareUploadResponseDto> {
}
}
impl SseEncode for Option<crate::api::discovery::RsDiscoveredDevice> {
impl SseEncode for Option<crate::api::discovery::RsStoredDevice> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<bool>::sse_encode(self.is_some(), serializer);
if let Some(value) = self {
<crate::api::discovery::RsDiscoveredDevice>::sse_encode(value, serializer);
<crate::api::discovery::RsStoredDevice>::sse_encode(value, serializer);
}
}
}
@@ -6931,22 +7007,6 @@ impl SseEncode for crate::api::model::ProtocolType {
}
}
impl SseEncode for crate::api::server::ProtocolTypeV2 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<i32>::sse_encode(
match self {
crate::api::server::ProtocolTypeV2::Http => 0,
crate::api::server::ProtocolTypeV2::Https => 1,
_ => {
unimplemented!("");
}
},
serializer,
);
}
}
impl SseEncode for (Dart2RustStreamSink, Dart2RustStreamReceiver) {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -6994,7 +7054,7 @@ impl SseEncode for crate::api::server::RegisterDtoV2 {
<Option<crate::api::model::DeviceType>>::sse_encode(self.device_type, serializer);
<String>::sse_encode(self.fingerprint, serializer);
<u16>::sse_encode(self.port, serializer);
<crate::api::server::ProtocolTypeV2>::sse_encode(self.protocol, serializer);
<crate::api::model::ProtocolType>::sse_encode(self.protocol, serializer);
<bool>::sse_encode(self.download, serializer);
}
}
@@ -7019,6 +7079,15 @@ impl SseEncode for crate::api::http::ResultWithPublicKeyRegisterResponseDto {
}
}
impl SseEncode for crate::api::discovery::RsDeviceChannel {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.host, serializer);
<u16>::sse_encode(self.port, serializer);
<crate::api::model::ProtocolType>::sse_encode(self.protocol, serializer);
}
}
impl SseEncode for crate::api::discovery::RsDiscoveredDevice {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -7029,7 +7098,7 @@ impl SseEncode for crate::api::discovery::RsDiscoveredDevice {
<String>::sse_encode(self.fingerprint, serializer);
<String>::sse_encode(self.host, serializer);
<u16>::sse_encode(self.port, serializer);
<crate::api::server::ProtocolTypeV2>::sse_encode(self.protocol, serializer);
<crate::api::model::ProtocolType>::sse_encode(self.protocol, serializer);
<bool>::sse_encode(self.download, serializer);
}
}
@@ -7165,6 +7234,19 @@ impl SseEncode for crate::api::server::RsServerEvent {
}
}
impl SseEncode for crate::api::discovery::RsStoredDevice {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.alias, serializer);
<String>::sse_encode(self.version, serializer);
<Option<String>>::sse_encode(self.device_model, serializer);
<Option<crate::api::model::DeviceType>>::sse_encode(self.device_type, serializer);
<String>::sse_encode(self.fingerprint, serializer);
<bool>::sse_encode(self.download, serializer);
<Vec<crate::api::discovery::RsDeviceChannel>>::sse_encode(self.channels, serializer);
}
}
impl SseEncode for crate::api::webrtc::RTCFileError {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {