use uuid::Uuid;
use super::device::DeviceState;
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VpnType {
WireGuard,
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct VpnCredentials {
pub vpn_type: VpnType,
pub name: String,
pub gateway: String,
pub private_key: String,
pub address: String,
pub peers: Vec<WireGuardPeer>,
pub dns: Option<Vec<String>>,
pub mtu: Option<u32>,
pub uuid: Option<Uuid>,
}
impl VpnCredentials {
pub fn new(
vpn_type: VpnType,
name: impl Into<String>,
gateway: impl Into<String>,
private_key: impl Into<String>,
address: impl Into<String>,
peers: Vec<WireGuardPeer>,
) -> Self {
Self {
vpn_type,
name: name.into(),
gateway: gateway.into(),
private_key: private_key.into(),
address: address.into(),
peers,
dns: None,
mtu: None,
uuid: None,
}
}
#[must_use]
pub fn builder() -> VpnCredentialsBuilder {
VpnCredentialsBuilder::default()
}
#[must_use]
pub fn with_dns(mut self, dns: Vec<String>) -> Self {
self.dns = Some(dns);
self
}
#[must_use]
pub fn with_mtu(mut self, mtu: u32) -> Self {
self.mtu = Some(mtu);
self
}
#[must_use]
pub fn with_uuid(mut self, uuid: Uuid) -> Self {
self.uuid = Some(uuid);
self
}
}
#[derive(Debug, Default)]
pub struct VpnCredentialsBuilder {
vpn_type: Option<VpnType>,
name: Option<String>,
gateway: Option<String>,
private_key: Option<String>,
address: Option<String>,
peers: Vec<WireGuardPeer>,
dns: Option<Vec<String>>,
mtu: Option<u32>,
uuid: Option<Uuid>,
}
impl VpnCredentialsBuilder {
#[must_use]
pub fn wireguard(mut self) -> Self {
self.vpn_type = Some(VpnType::WireGuard);
self
}
#[must_use]
pub fn vpn_type(mut self, vpn_type: VpnType) -> Self {
self.vpn_type = Some(vpn_type);
self
}
#[must_use]
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
#[must_use]
pub fn gateway(mut self, gateway: impl Into<String>) -> Self {
self.gateway = Some(gateway.into());
self
}
#[must_use]
pub fn private_key(mut self, private_key: impl Into<String>) -> Self {
self.private_key = Some(private_key.into());
self
}
#[must_use]
pub fn address(mut self, address: impl Into<String>) -> Self {
self.address = Some(address.into());
self
}
#[must_use]
pub fn add_peer(mut self, peer: WireGuardPeer) -> Self {
self.peers.push(peer);
self
}
#[must_use]
pub fn peers(mut self, peers: Vec<WireGuardPeer>) -> Self {
self.peers = peers;
self
}
#[must_use]
pub fn with_dns(mut self, dns: Vec<String>) -> Self {
self.dns = Some(dns);
self
}
#[must_use]
pub fn with_mtu(mut self, mtu: u32) -> Self {
self.mtu = Some(mtu);
self
}
#[must_use]
pub fn with_uuid(mut self, uuid: Uuid) -> Self {
self.uuid = Some(uuid);
self
}
#[must_use]
pub fn build(self) -> VpnCredentials {
VpnCredentials {
vpn_type: self
.vpn_type
.expect("vpn_type is required (use .wireguard())"),
name: self.name.expect("name is required (use .name())"),
gateway: self.gateway.expect("gateway is required (use .gateway())"),
private_key: self
.private_key
.expect("private_key is required (use .private_key())"),
address: self.address.expect("address is required (use .address())"),
peers: {
if self.peers.is_empty() {
panic!("at least one peer is required (use .add_peer())");
}
self.peers
},
dns: self.dns,
mtu: self.mtu,
uuid: self.uuid,
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct WireGuardPeer {
pub public_key: String,
pub gateway: String,
pub allowed_ips: Vec<String>,
pub preshared_key: Option<String>,
pub persistent_keepalive: Option<u32>,
}
impl WireGuardPeer {
pub fn new(
public_key: impl Into<String>,
gateway: impl Into<String>,
allowed_ips: Vec<String>,
) -> Self {
Self {
public_key: public_key.into(),
gateway: gateway.into(),
allowed_ips,
preshared_key: None,
persistent_keepalive: None,
}
}
#[must_use]
pub fn with_preshared_key(mut self, psk: impl Into<String>) -> Self {
self.preshared_key = Some(psk.into());
self
}
#[must_use]
pub fn with_persistent_keepalive(mut self, interval: u32) -> Self {
self.persistent_keepalive = Some(interval);
self
}
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct VpnConnection {
pub name: String,
pub vpn_type: VpnType,
pub state: DeviceState,
pub interface: Option<String>,
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct VpnConnectionInfo {
pub name: String,
pub vpn_type: VpnType,
pub state: DeviceState,
pub interface: Option<String>,
pub gateway: Option<String>,
pub ip4_address: Option<String>,
pub ip6_address: Option<String>,
pub dns_servers: Vec<String>,
}