playit-gg 0.0.8

Unofficial Rust wrapper for https://playit.gg
Documentation
use reqwest::blocking::Client;
use serde::Deserialize;
use serde::Serialize;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ops::Index;
use std::path::PathBuf;
use std::process::Child as _Child;
use url::Url;

#[allow(non_snake_case)]
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct PlayItOpts {
  pub PREFERRED_TUNNEL: Option<String>,
  pub PREFERRED_THRESHOLD: Option<u16>,
  pub NO_SPECIAL_LAN: Option<bool>,
  // pub KEEP_CONFIG: Option<bool>,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Tunnel {
  pub id: u32,
  pub agent_id: u32,
  pub game: String,
  pub local_ip: String,
  pub local_port: u16,
  pub domain_id: Option<u32>,
  pub status: String,
  pub connect_address: Option<String>,
  pub is_custom_domain: bool,
  pub tunnel_version: Option<u8>,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Tunnels {
  pub tunnels: Vec<Tunnel>,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Connection {
  pub ip: String,
  pub tunnel: Tunnel,
  pub proto: Prototype,
}

#[derive(Debug)]
pub struct PlayIt {
  pub req_client: Client,
  pub os: OS,
  pub config_file: PathBuf,
  pub arch: Arch,
  pub dir: PathBuf,
  pub destroyed: bool,
  pub tunnels: Vec<Tunnel>,
  pub agent_key: String,
  pub started: bool,
  pub playit: Child,
  pub server: String,
  pub used_packets: u8,
  pub free_packets: u8,
  pub connections: Vec<Connection>,
  pub version: String,
  pub download_urls: Binaries,
  pub binary: PathBuf,
  pub binary_type: BinaryType,
  pub output: Vec<String>,
  pub stdout: Vec<String>,
  pub stderr: Vec<String>,
  pub errors: Vec<String>,
  pub warnings: Vec<String>,
  pub api_path: Url,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Agent {
  pub tunnel_server_name: Option<String>,
  pub host_ip: Option<String>,
  pub is_connected: bool,
  pub key: String,
  pub id: u32,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Agents {
  pub agents: Vec<Agent>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct Binaries {
  pub win: Url,
  pub lin: Url,
  pub mac: Url,
  pub arm64: Url,
  pub arm: Url,
}

impl Index<BinaryType> for Binaries {
  type Output = Url;

  fn index(&self, binary_type: BinaryType) -> &Self::Output {
    match binary_type {
      BinaryType::Windows => &self.win,
      BinaryType::Linux => &self.lin,
      BinaryType::MacOS => &self.mac,
      BinaryType::Arm64 => &self.arm64,
      BinaryType::Arm => &self.arm,
      _ => panic!("Unknown Index: {:#?}", binary_type),
    }
  }
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Config {
  pub agent_key: Option<String>,
  pub preferred_tunnel: Option<String>,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Id {
  pub id: u32,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub enum Prototype {
  Tcp,
  Udp,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub enum OS {
  Windows,
  Linux,
  MacOS,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub enum Arch {
  X64,
  Arm64,
  Arm,
  Unsupported,
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub enum BinaryType {
  Windows,
  Linux,
  MacOS,
  Arm64,
  Arm,
  Unsupported,
}

#[allow(non_camel_case_types)]
pub enum Servers {
  dal4,
  sol4,
  syd4,
  mum4,
  sf4,
  fnk4,
  bng4,
  sng4,
  tor4,
  ny4,
  uk4,
  saw4,
  turk4,
  san4,
  pet4,
  bur4,
  new4,
  isr4,
  tko4,
  syd5,
  sng5,
  hel4,
  fal4,
}

// https://doc.rust-lang.org/std/process/struct.Child.html
/// Representation of a running or exited child process.
///
/// This structure is used to represent and manage child processes. A child
/// process is created via the [`Command`] struct, which configures the
/// spawning process and can itself be constructed using a builder-style
/// interface.
///
/// There is no implementation of [`Drop`] for child processes,
/// so if you do not ensure the `Child` has exited then it will continue to
/// run, even after the `Child` handle to the child process has gone out of
/// scope.
///
/// Calling [`wait`] (or other functions that wrap around it) will make
/// the parent process wait until the child has actually exited before
/// continuing.
///
/// # Warning
///
/// On some systems, calling [`wait`] or similar is necessary for the OS to
/// release resources. A process that terminated but has not been waited on is
/// still around as a "zombie". Leaving too many zombies around may exhaust
/// global resources (for example process IDs).
///
/// The standard library does *not* automatically wait on child processes (not
/// even if the `Child` is dropped), it is up to the application developer to do
/// so. As a consequence, dropping `Child` handles without waiting on them first
/// is not recommended in long-running applications.
///
/// # Examples
///
/// ```should_panic
/// use std::process::Command;
///
/// let mut child = Command::new("/bin/cat")
///                         .arg("file.txt")
///                         .spawn()
///                         .expect("failed to execute child");
///
/// let ecode = child.wait()
///                  .expect("failed to wait on child");
///
/// assert!(ecode.success());
/// ```
///
#[derive(Debug)]
pub struct Child(pub _Child);

impl Drop for Child {
  fn drop(&mut self) {
    self.0.kill().ok();
  }
}

impl Deref for Child {
  type Target = _Child;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

impl DerefMut for Child {
  fn deref_mut(&mut self) -> &mut _Child {
    &mut self.0
  }
}