Compare commits
1 Commits
main
...
36821ec329
Author | SHA1 | Date | |
---|---|---|---|
36821ec329 |
49
CHANGELOG.md
49
CHANGELOG.md
@@ -6,55 +6,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## [0.0.4] - 2025-08-03
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- pipe output
|
|
||||||
- replace bytes with string to avoid endianness
|
|
||||||
- sanitise output
|
|
||||||
- replace output spawn with native tokio method
|
|
||||||
|
|
||||||
### Other
|
|
||||||
- add print to output from paste
|
|
||||||
|
|
||||||
## [0.0.3] - 2025-08-03
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- don't use front
|
|
||||||
- add paste command both local and remote
|
|
||||||
- add publish
|
|
||||||
|
|
||||||
### Other
|
|
||||||
- test commit
|
|
||||||
|
|
||||||
|
|
||||||
## [0.0.2] - 2025-08-02
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- voidpin now copies to linux as well
|
|
||||||
- add demo gif
|
|
||||||
- add basic remote copu
|
|
||||||
|
|
||||||
### Docs
|
|
||||||
- add more thorough example
|
|
||||||
- correct docs
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- *(deps)* update all dependencies (#16)
|
|
||||||
- *(deps)* update rust crate bytes to v1.10.1
|
|
||||||
- *(deps)* update rust crate serde to v1.0.218
|
|
||||||
- *(deps)* update tokio-prost monorepo to v0.13.5
|
|
||||||
- *(deps)* update rust crate uuid to v1.13.1
|
|
||||||
- *(deps)* update all dependencies
|
|
||||||
- *(deps)* update rust crate uuid to v1.12.0
|
|
||||||
|
|
||||||
### Other
|
|
||||||
- *(deps)* update all dependencies
|
|
||||||
- *(deps)* update all dependencies
|
|
||||||
- *(deps)* update all dependencies
|
|
||||||
- *(deps)* update rust crate clap to v4.5.29
|
|
||||||
- fix demo
|
|
||||||
|
|
||||||
## [0.0.1] - 2025-01-10
|
## [0.0.1] - 2025-01-10
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
521
Cargo.lock
generated
521
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ members = ["crates/*"]
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.0.4"
|
version = "0.0.1"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
voidpin = { path = "crates/voidpin" }
|
voidpin = { path = "crates/voidpin" }
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "voidpin"
|
name = "voidpin"
|
||||||
edition = "2024"
|
edition = "2021"
|
||||||
readme = "../../README.md"
|
|
||||||
license = "MIT"
|
|
||||||
authors = ["kjuulh <contact@kasperhermansen.com>"]
|
|
||||||
repository = "https://git.kjuulh.io/kjuulh/voidpin.git"
|
|
||||||
description = "Voidpin allows sending copy/paste commands across the wire. It is specifically intended for use in ssh tunnels for long running sessions, where you want to share a clipboard. The primary use case is when a remote machine is used for development, but clipboard continues to be an ergonomic hurdle."
|
|
||||||
|
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
@@ -13,7 +8,7 @@ version.workspace = true
|
|||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
tracing-subscriber = { workspace = true, features = ["env-filter"] }
|
tracing-subscriber.workspace = true
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
dotenv.workspace = true
|
dotenv.workspace = true
|
||||||
|
|
||||||
|
@@ -2,20 +2,12 @@ syntax = "proto3";
|
|||||||
|
|
||||||
package voidpin.v1;
|
package voidpin.v1;
|
||||||
|
|
||||||
|
service VoidPin {
|
||||||
|
rpc Copy(CopyRequest) returns (CopyResponse);
|
||||||
|
}
|
||||||
|
|
||||||
message CopyRequest {
|
message CopyRequest {
|
||||||
string content = 1;
|
bytes content = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CopyResponse {}
|
message CopyResponse {}
|
||||||
|
|
||||||
message PasteRequest {
|
|
||||||
}
|
|
||||||
|
|
||||||
message PasteResponse {
|
|
||||||
string content = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
service VoidPin {
|
|
||||||
rpc Copy(CopyRequest) returns (CopyResponse);
|
|
||||||
rpc Paste(PasteRequest) returns (PasteResponse);
|
|
||||||
}
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
|
|
||||||
@@ -15,22 +15,9 @@ impl LocalCopier {
|
|||||||
|
|
||||||
pub async fn copy(&self, input: &[u8]) -> anyhow::Result<()> {
|
pub async fn copy(&self, input: &[u8]) -> anyhow::Result<()> {
|
||||||
// FIXME: hardcode for macos
|
// FIXME: hardcode for macos
|
||||||
#[cfg(target_os = "macos")]
|
let mut copy_process = tokio::process::Command::new("pbcopy")
|
||||||
let mut copy_process = {
|
|
||||||
tokio::process::Command::new("pbcopy")
|
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.spawn()?
|
.spawn()?;
|
||||||
};
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
let mut copy_process = {
|
|
||||||
tokio::process::Command::new("wl-copy")
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.spawn()?
|
|
||||||
};
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
let mut copy_process = {
|
|
||||||
todo!("windows not supported yet");
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(mut stdin_handle) = copy_process.stdin.take() {
|
if let Some(mut stdin_handle) = copy_process.stdin.take() {
|
||||||
stdin_handle
|
stdin_handle
|
||||||
@@ -48,41 +35,6 @@ impl LocalCopier {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn paste(&self) -> anyhow::Result<Vec<u8>> {
|
|
||||||
// FIXME: hardcode for macos
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
let paste_process = {
|
|
||||||
tokio::process::Command::new("pbpaste")
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.spawn()?
|
|
||||||
};
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
let mut paste_process = {
|
|
||||||
tokio::process::Command::new("wl-paste")
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.spawn()?
|
|
||||||
};
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
let mut paste_process = {
|
|
||||||
todo!("windows not supported yet");
|
|
||||||
};
|
|
||||||
|
|
||||||
let output = paste_process.wait_with_output().await?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
anyhow::bail!(
|
|
||||||
"output failed with: {}, {}, exit_code: {}",
|
|
||||||
std::str::from_utf8(&output.stdout).unwrap_or_default(),
|
|
||||||
std::str::from_utf8(&output.stderr).unwrap_or_default(),
|
|
||||||
output.status.code().unwrap_or_default(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(output.stdout)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LocalCopierState {
|
pub trait LocalCopierState {
|
||||||
|
@@ -3,22 +3,12 @@
|
|||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct CopyRequest {
|
pub struct CopyRequest {
|
||||||
#[prost(string, tag="1")]
|
#[prost(bytes="vec", tag="1")]
|
||||||
pub content: ::prost::alloc::string::String,
|
pub content: ::prost::alloc::vec::Vec<u8>,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
||||||
pub struct CopyResponse {
|
pub struct CopyResponse {
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
|
||||||
pub struct PasteRequest {
|
|
||||||
}
|
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct PasteResponse {
|
|
||||||
#[prost(string, tag="1")]
|
|
||||||
pub content: ::prost::alloc::string::String,
|
|
||||||
}
|
|
||||||
include!("voidpin.v1.tonic.rs");
|
include!("voidpin.v1.tonic.rs");
|
||||||
// @@protoc_insertion_point(module)
|
// @@protoc_insertion_point(module)
|
@@ -105,26 +105,6 @@ pub mod void_pin_client {
|
|||||||
req.extensions_mut().insert(GrpcMethod::new("voidpin.v1.VoidPin", "Copy"));
|
req.extensions_mut().insert(GrpcMethod::new("voidpin.v1.VoidPin", "Copy"));
|
||||||
self.inner.unary(req, path, codec).await
|
self.inner.unary(req, path, codec).await
|
||||||
}
|
}
|
||||||
///
|
|
||||||
pub async fn paste(
|
|
||||||
&mut self,
|
|
||||||
request: impl tonic::IntoRequest<super::PasteRequest>,
|
|
||||||
) -> std::result::Result<tonic::Response<super::PasteResponse>, tonic::Status> {
|
|
||||||
self.inner
|
|
||||||
.ready()
|
|
||||||
.await
|
|
||||||
.map_err(|e| {
|
|
||||||
tonic::Status::new(
|
|
||||||
tonic::Code::Unknown,
|
|
||||||
format!("Service was not ready: {}", e.into()),
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
|
||||||
let path = http::uri::PathAndQuery::from_static("/voidpin.v1.VoidPin/Paste");
|
|
||||||
let mut req = request.into_request();
|
|
||||||
req.extensions_mut().insert(GrpcMethod::new("voidpin.v1.VoidPin", "Paste"));
|
|
||||||
self.inner.unary(req, path, codec).await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Generated server implementations.
|
/// Generated server implementations.
|
||||||
@@ -139,11 +119,6 @@ pub mod void_pin_server {
|
|||||||
&self,
|
&self,
|
||||||
request: tonic::Request<super::CopyRequest>,
|
request: tonic::Request<super::CopyRequest>,
|
||||||
) -> std::result::Result<tonic::Response<super::CopyResponse>, tonic::Status>;
|
) -> std::result::Result<tonic::Response<super::CopyResponse>, tonic::Status>;
|
||||||
///
|
|
||||||
async fn paste(
|
|
||||||
&self,
|
|
||||||
request: tonic::Request<super::PasteRequest>,
|
|
||||||
) -> std::result::Result<tonic::Response<super::PasteResponse>, tonic::Status>;
|
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -269,50 +244,6 @@ pub mod void_pin_server {
|
|||||||
};
|
};
|
||||||
Box::pin(fut)
|
Box::pin(fut)
|
||||||
}
|
}
|
||||||
"/voidpin.v1.VoidPin/Paste" => {
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
struct PasteSvc<T: VoidPin>(pub Arc<T>);
|
|
||||||
impl<T: VoidPin> tonic::server::UnaryService<super::PasteRequest>
|
|
||||||
for PasteSvc<T> {
|
|
||||||
type Response = super::PasteResponse;
|
|
||||||
type Future = BoxFuture<
|
|
||||||
tonic::Response<Self::Response>,
|
|
||||||
tonic::Status,
|
|
||||||
>;
|
|
||||||
fn call(
|
|
||||||
&mut self,
|
|
||||||
request: tonic::Request<super::PasteRequest>,
|
|
||||||
) -> Self::Future {
|
|
||||||
let inner = Arc::clone(&self.0);
|
|
||||||
let fut = async move {
|
|
||||||
<T as VoidPin>::paste(&inner, request).await
|
|
||||||
};
|
|
||||||
Box::pin(fut)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let accept_compression_encodings = self.accept_compression_encodings;
|
|
||||||
let send_compression_encodings = self.send_compression_encodings;
|
|
||||||
let max_decoding_message_size = self.max_decoding_message_size;
|
|
||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
|
||||||
let inner = self.inner.clone();
|
|
||||||
let fut = async move {
|
|
||||||
let inner = inner.0;
|
|
||||||
let method = PasteSvc(inner);
|
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
|
||||||
.apply_compression_config(
|
|
||||||
accept_compression_encodings,
|
|
||||||
send_compression_encodings,
|
|
||||||
)
|
|
||||||
.apply_max_message_size_config(
|
|
||||||
max_decoding_message_size,
|
|
||||||
max_encoding_message_size,
|
|
||||||
);
|
|
||||||
let res = grpc.unary(method, req).await;
|
|
||||||
Ok(res)
|
|
||||||
};
|
|
||||||
Box::pin(fut)
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
Ok(
|
Ok(
|
||||||
|
@@ -1,8 +1,4 @@
|
|||||||
use crate::{
|
use crate::{copy::LocalCopierState, state::State};
|
||||||
copy::LocalCopierState,
|
|
||||||
grpc::{PasteRequest, PasteResponse},
|
|
||||||
state::State,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GrpcServer {
|
pub struct GrpcServer {
|
||||||
@@ -25,26 +21,10 @@ impl crate::grpc::void_pin_server::VoidPin for GrpcServer {
|
|||||||
|
|
||||||
self.state
|
self.state
|
||||||
.local_copier()
|
.local_copier()
|
||||||
.copy(&req.content.as_bytes())
|
.copy(&req.content)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| tonic::Status::internal(e.to_string()))?;
|
.map_err(|e| tonic::Status::internal(e.to_string()))?;
|
||||||
|
|
||||||
Ok(tonic::Response::new(crate::grpc::CopyResponse {}))
|
Ok(tonic::Response::new(crate::grpc::CopyResponse {}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn paste(
|
|
||||||
&self,
|
|
||||||
_request: tonic::Request<PasteRequest>,
|
|
||||||
) -> std::result::Result<tonic::Response<PasteResponse>, tonic::Status> {
|
|
||||||
let output = self
|
|
||||||
.state
|
|
||||||
.local_copier()
|
|
||||||
.paste()
|
|
||||||
.await
|
|
||||||
.map_err(|e| tonic::Status::internal(e.to_string()))?;
|
|
||||||
|
|
||||||
Ok(tonic::Response::new(crate::grpc::PasteResponse {
|
|
||||||
content: String::from_utf8_lossy(&output).to_string(),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -7,9 +7,7 @@ use grpc::void_pin_server::VoidPinServer;
|
|||||||
use grpc_server::GrpcServer;
|
use grpc_server::GrpcServer;
|
||||||
use remote_copy::RemoteCopierState;
|
use remote_copy::RemoteCopierState;
|
||||||
use state::State;
|
use state::State;
|
||||||
use tokio::io::AsyncWriteExt;
|
|
||||||
use tonic::transport;
|
use tonic::transport;
|
||||||
use tracing_subscriber::EnvFilter;
|
|
||||||
|
|
||||||
mod grpc {
|
mod grpc {
|
||||||
include!("gen/voidpin.v1.rs");
|
include!("gen/voidpin.v1.rs");
|
||||||
@@ -35,7 +33,6 @@ enum Commands {
|
|||||||
grpc: SocketAddr,
|
grpc: SocketAddr,
|
||||||
},
|
},
|
||||||
Copy {},
|
Copy {},
|
||||||
Paste {},
|
|
||||||
Remote {
|
Remote {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: RemoteCommands,
|
command: RemoteCommands,
|
||||||
@@ -52,27 +49,12 @@ enum RemoteCommands {
|
|||||||
)]
|
)]
|
||||||
remote_host: String,
|
remote_host: String,
|
||||||
},
|
},
|
||||||
Paste {
|
|
||||||
#[arg(
|
|
||||||
long = "remote-host",
|
|
||||||
env = "VOIDPIN_REMOTE",
|
|
||||||
default_value = "http://0.0.0.0:7900"
|
|
||||||
)]
|
|
||||||
remote_host: String,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt::init();
|
||||||
.with_env_filter(
|
|
||||||
EnvFilter::builder()
|
|
||||||
//.with_default_directive("error".parse().unwrap())
|
|
||||||
.from_env_lossy(),
|
|
||||||
)
|
|
||||||
.with_writer(std::io::stderr)
|
|
||||||
.init();
|
|
||||||
|
|
||||||
let cli = Command::parse();
|
let cli = Command::parse();
|
||||||
tracing::debug!("Starting cli");
|
tracing::debug!("Starting cli");
|
||||||
@@ -88,23 +70,6 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
Commands::Copy {} => {
|
Commands::Copy {} => {
|
||||||
if let Ok(remote_host) = std::env::var("VOIDPIN_REMOTE") {
|
|
||||||
let mut input = String::new();
|
|
||||||
std::io::stdin()
|
|
||||||
.read_to_string(&mut input)
|
|
||||||
.context("failed to read from stdin")?;
|
|
||||||
|
|
||||||
if input.is_empty() {
|
|
||||||
tracing::info!("no content to put in clipboard");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
tracing::debug!(content = &input, "found content");
|
|
||||||
state.remote_copier(&remote_host).copy(input).await?;
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
std::io::stdin()
|
std::io::stdin()
|
||||||
.read_to_string(&mut input)
|
.read_to_string(&mut input)
|
||||||
@@ -118,22 +83,6 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
tracing::debug!(content = &input, "found content");
|
tracing::debug!(content = &input, "found content");
|
||||||
state.local_copier().copy(input.as_bytes()).await?;
|
state.local_copier().copy(input.as_bytes()).await?;
|
||||||
}
|
}
|
||||||
Commands::Paste {} => {
|
|
||||||
let mut stdout = tokio::io::stdout();
|
|
||||||
|
|
||||||
if let Ok(remote_host) = std::env::var("VOIDPIN_REMOTE") {
|
|
||||||
let output = state.remote_copier(&remote_host).paste().await?;
|
|
||||||
|
|
||||||
stdout.write_all(output.as_bytes()).await?;
|
|
||||||
stdout.flush().await?;
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let output = state.local_copier().paste().await?;
|
|
||||||
stdout.write_all(&output).await?;
|
|
||||||
stdout.flush().await?;
|
|
||||||
}
|
|
||||||
Commands::Remote { command } => match command {
|
Commands::Remote { command } => match command {
|
||||||
RemoteCommands::Copy { remote_host } => {
|
RemoteCommands::Copy { remote_host } => {
|
||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
@@ -147,16 +96,13 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tracing::debug!(content = &input, "found content");
|
tracing::debug!(content = &input, "found content");
|
||||||
state.remote_copier(&remote_host).copy(input).await?;
|
state
|
||||||
}
|
.remote_copier(&remote_host)
|
||||||
RemoteCommands::Paste { remote_host } => {
|
.copy(input.as_bytes())
|
||||||
let output = state.remote_copier(&remote_host).paste().await?;
|
.await?;
|
||||||
|
|
||||||
let mut stdout = tokio::io::stdout();
|
|
||||||
stdout.write_all(output.as_bytes()).await?;
|
|
||||||
stdout.flush().await?;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
use tonic::transport::{Channel, ClientTlsConfig};
|
use tonic::transport::{Channel, ClientTlsConfig};
|
||||||
|
|
||||||
use crate::{
|
use crate::{grpc::CopyRequest, state::State};
|
||||||
grpc::{CopyRequest, PasteRequest},
|
|
||||||
state::State,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RemoteCopier {
|
pub struct RemoteCopier {
|
||||||
@@ -17,7 +14,7 @@ impl RemoteCopier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn copy(&self, input: String) -> anyhow::Result<()> {
|
pub async fn copy(&self, input: &[u8]) -> anyhow::Result<()> {
|
||||||
let tls = ClientTlsConfig::new();
|
let tls = ClientTlsConfig::new();
|
||||||
let channel = Channel::from_shared(self.host.clone())?
|
let channel = Channel::from_shared(self.host.clone())?
|
||||||
.tls_config(if self.host.starts_with("https") {
|
.tls_config(if self.host.starts_with("https") {
|
||||||
@@ -40,29 +37,6 @@ impl RemoteCopier {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn paste(&self) -> anyhow::Result<String> {
|
|
||||||
let tls = ClientTlsConfig::new();
|
|
||||||
let channel = Channel::from_shared(self.host.clone())?
|
|
||||||
.tls_config(if self.host.starts_with("https") {
|
|
||||||
tls.with_native_roots()
|
|
||||||
} else {
|
|
||||||
tls
|
|
||||||
})?
|
|
||||||
.connect()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
tracing::debug!("establishing connection to remote");
|
|
||||||
let mut client = crate::grpc::void_pin_client::VoidPinClient::new(channel);
|
|
||||||
|
|
||||||
tracing::info!("sending paste request");
|
|
||||||
let resp = client.paste(PasteRequest {}).await?;
|
|
||||||
|
|
||||||
let output = resp.into_inner().content;
|
|
||||||
tracing::info!(content = output, "received paste response");
|
|
||||||
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait RemoteCopierState {
|
pub trait RemoteCopierState {
|
||||||
|
@@ -5,8 +5,6 @@ base: "git@git.front.kjuulh.io:kjuulh/cuddle-rust-cli-plan.git"
|
|||||||
vars:
|
vars:
|
||||||
service: "voidpin"
|
service: "voidpin"
|
||||||
registry: kasperhermansen
|
registry: kasperhermansen
|
||||||
rust:
|
|
||||||
publish: {}
|
|
||||||
|
|
||||||
please:
|
please:
|
||||||
project:
|
project:
|
||||||
@@ -14,6 +12,6 @@ please:
|
|||||||
repository: "voidpin"
|
repository: "voidpin"
|
||||||
branch: "main"
|
branch: "main"
|
||||||
settings:
|
settings:
|
||||||
api_url: "https://git.kjuulh.io"
|
api_url: "https://git.front.kjuulh.io"
|
||||||
actions:
|
actions:
|
||||||
rust:
|
rust:
|
||||||
|
Reference in New Issue
Block a user