1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crateCountryCode;
use IpAddr;
/// Resolver interface for mapping `IpAddr` → `CountryCode`.
///
/// IP Flag does not include geolocation data. To get a real country result, your
/// application (or an extension crate) must implement this trait.
///
/// The resolver is only called for public IPs (`IpScope::Public`). Private and
/// special addresses never call this function.
///
/// # Return value
/// - `Ok(Some(code))`: country found, displayed as `🇰🇷 KR`
/// - `Ok(None)`: unknown country, displayed as `🌐 UNKNOWN`
/// - `Err(e)`: resolver failure (database not found, corrupted data, etc.)
///
/// # Example (demo only)
///
/// ```rust
/// use ipflag::{CountryCode, IpResolver, tag_ip};
/// use std::net::IpAddr;
///
/// struct AlwaysCN;
/// impl IpResolver for AlwaysCN {
/// type Error = core::convert::Infallible;
/// fn resolve(&self, _ip: IpAddr) -> Result<Option<CountryCode>, Self::Error> {
/// Ok(CountryCode::new("CN"))
/// }
/// }
///
/// let tag = tag_ip(&AlwaysCN, "8.8.8.8").unwrap();
/// assert_eq!(tag.to_string(), "🇨🇳 CN");
/// ```
///
/// For real-world usage, back this resolver with a real data source (GeoIP DB).
/// A built-in resolver that never resolves any public IP.
///
/// This is provided so IP Flag remains useful out-of-the-box:
/// - private IPs → 🏠 PRIVATE
/// - special IPs → ⚙️ SPECIAL
/// - public IPs → 🌐 UNKNOWN
///
/// Useful for UI scaffolding, tests, or when you only want scope classification.
;