Skip to main content

oxy_upnp_igd/
error.rs

1/* This file is part of oxy-upnp-igd
2 *
3 * Copyright (C) 2026 Gioacchino Mazzurco <gio@polymathes.cc>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19//! Error types for UPnP IGD operations
20
21use std::io;
22
23pub type Result<T> = std::result::Result<T, Error>;
24
25#[derive(Debug, thiserror::Error)]
26pub enum Error {
27    #[error("I/O error: {0}")]
28    Io(#[from] io::Error),
29
30    #[error("HTTP error: {0}")]
31    Http(String),
32
33    #[error("XML parsing error: {0}")]
34    Xml(String),
35
36    #[error("No UPnP gateway found")]
37    NoGatewayFound,
38
39    #[error("Invalid response from gateway: {0}")]
40    InvalidResponse(String),
41
42    #[error("Port mapping failed: {0}")]
43    PortMappingFailed(String),
44
45    #[error("Gateway error: {0}")]
46    GatewayError(String),
47
48    #[error("URL parse error: {0}")]
49    UrlParse(#[from] url::ParseError),
50
51    #[error("Invalid protocol: {0}")]
52    InvalidProtocol(String),
53
54    #[error("UPnP error code {code}: {description}")]
55    UpnpErrorCode { code: u32, description: String },
56}
57
58impl Clone for Error {
59    fn clone(&self) -> Self {
60        match self {
61            Self::Io(err) => Self::Http(err.to_string()),
62            Self::Http(s) => Self::Http(s.clone()),
63            Self::Xml(s) => Self::Xml(s.clone()),
64            Self::NoGatewayFound => Self::NoGatewayFound,
65            Self::InvalidResponse(s) => Self::InvalidResponse(s.clone()),
66            Self::PortMappingFailed(s) => Self::PortMappingFailed(s.clone()),
67            Self::GatewayError(s) => Self::GatewayError(s.clone()),
68            Self::UrlParse(e) => Self::UrlParse(*e),
69            Self::InvalidProtocol(s) => Self::InvalidProtocol(s.clone()),
70            Self::UpnpErrorCode { code, description } => Self::UpnpErrorCode {
71                code: *code,
72                description: description.clone(),
73            },
74        }
75    }
76}