two-way file system sync
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cli.rs 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. use std::io::{self, Write};
  2. use std::net::Shutdown;
  3. use std::os::unix::net::UnixStream;
  4. use std::path::PathBuf;
  5. use byteorder::{BigEndian, ReadBytesExt};
  6. use serde::{Deserialize, Serialize};
  7. use structopt::StructOpt;
  8. pub fn socket_path() -> String {
  9. format!(
  10. "{}/.twfss/sock",
  11. dirs::home_dir().unwrap().to_str().unwrap().to_owned()
  12. )
  13. }
  14. #[derive(StructOpt, Serialize, Deserialize)]
  15. #[structopt(about = "CLI for the two-way file system sync client")]
  16. pub struct Options {
  17. #[structopt(long)]
  18. pub verbose: bool,
  19. #[structopt(subcommand)]
  20. pub command: Command,
  21. }
  22. #[derive(StructOpt, Serialize, Deserialize)]
  23. pub enum Command {
  24. ListDirectories {
  25. status: bool,
  26. },
  27. AddDirectory {
  28. // TODO: Login information.
  29. local_directory: PathBuf,
  30. remote_url: String,
  31. },
  32. RemoveDirectory {
  33. local_directory: PathBuf,
  34. },
  35. // TODO: Command to update login information in case of login problems.
  36. }
  37. // The file is included in the sync client, where main() is unused.
  38. #[allow(unused)]
  39. fn main() {
  40. let options = Options::from_args();
  41. // We simply send the options to the server and print whatever the server returns.
  42. let mut client = match SyncClient::connect() {
  43. Ok(client) => client,
  44. Err(err) => {
  45. println!(
  46. "Could not connect to the sync client. Make sure that the sync client is running."
  47. );
  48. println!("Error: {:?}", err);
  49. std::process::exit(-1);
  50. }
  51. };
  52. let return_code = client.execute(options).unwrap();
  53. std::process::exit(return_code);
  54. }
  55. struct SyncClient {
  56. stream: UnixStream,
  57. }
  58. impl SyncClient {
  59. fn connect() -> Result<SyncClient, Error> {
  60. let stream = UnixStream::connect(socket_path()).unwrap();
  61. Ok(SyncClient { stream })
  62. }
  63. fn execute(&mut self, options: Options) -> Result<i32, Error> {
  64. let json = serde_json::to_string(&options)?;
  65. self.stream.write_all(json.as_bytes())?;
  66. self.stream.shutdown(Shutdown::Write).unwrap();
  67. // The first 4 bytes are the return value.
  68. let return_value = self.stream.read_i32::<BigEndian>()?;
  69. // Print all the output returned by the server.
  70. io::copy(&mut self.stream, &mut io::stdout())?;
  71. Ok(return_value)
  72. }
  73. }
  74. #[derive(Debug)]
  75. enum Error {
  76. Json(serde_json::error::Error),
  77. Io(std::io::Error),
  78. }
  79. impl From<serde_json::error::Error> for Error {
  80. fn from(e: serde_json::error::Error) -> Error {
  81. Error::Json(e)
  82. }
  83. }
  84. impl From<io::Error> for Error {
  85. fn from(e: io::Error) -> Error {
  86. Error::Io(e)
  87. }
  88. }