region_cn/
lib.rs

1/*!
2根据 中国 6 位行政区划代码查询地区名称
3
4基本用法:
5
6```
7use std::path::PathBuf;
8
9use region_cn::region::Region;
10
11let mut region = Region::new(PathBuf::from("data/region.dat"));
12// 直接在region.dat中搜索
13match region.search_with_data("530925") {
14    Ok(data) => {
15        println!("{:#?}", data);
16        assert_eq!(data.name, "云南省临沧市双江拉祜族佤族布朗族傣族自治县");
17        assert_eq!(
18            data.region_slice,
19            vec!["云南省", "临沧市", "双江拉祜族佤族布朗族傣族自治县",]
20        );
21    }
22    Err(e) => eprintln!("{}", e),
23}
24// 通过前缀树来搜索结果
25let result = region.search_with_trie("530925").unwrap();
26assert_eq!(result.name, "云南省临沧市双江拉祜族佤族布朗族傣族自治县");
27```
28*/
29
30pub mod region;
31pub mod trie;
32
33use std::{fmt, num::ParseIntError};
34
35/// RegionItem
36#[derive(Debug)]
37pub struct RegionItem {
38    /// 地区代码
39    pub region_code: String,
40    /// 地区全称
41    pub name: String,
42    /// 一级 二级 三级 地区名称
43    pub region_slice: Vec<String>,
44    /// 废止的年份,为0表示未废止
45    pub discard_year: u32,
46}
47
48/// 大端字节序列转成i32
49pub(crate) fn be_u8_slice_to_i32(bytes: &[u8]) -> i32 {
50    let mut res = 0;
51    let length = bytes.len();
52    for (i, b) in bytes.iter().enumerate() {
53        res += (*b as i32) << ((length - i - 1) * 8)
54    }
55    res
56}
57
58/// 将vec[u8]解析成12位的数组
59pub(crate) fn decode_u8_list(u8_list: &Vec<u8>) -> (Vec<u32>, u32) {
60    // 按4bit分割, 再3个组合成12位
61    let mut four_bits: Vec<u8> = Vec::new();
62    for u8_val in u8_list {
63        four_bits.push((u8_val & 0xF0) >> 4); // 高4位
64        four_bits.push(u8_val & 0x0F); // 低4位
65    }
66
67    let mut res: Vec<u32> = Vec::new();
68    for i in 0..four_bits.len() / 3 {
69        let a = four_bits[3 * i] as u32;
70        let b = four_bits[3 * i + 1] as u32;
71        let c = four_bits[3 * i + 2] as u32;
72        let num = (a << 8) + (b << 4) + c;
73        if num >= 64 {
74            res.push(num);
75        }
76    }
77
78    let mut discard_year_int: u32 = 0;
79    let last_four_bits = &four_bits[res.len() * 3..];
80    for (i, &b) in last_four_bits.iter().enumerate() {
81        discard_year_int += (b as u32) << (4 * (last_four_bits.len() - i - 1));
82    }
83
84    (res, discard_year_int)
85}
86
87/// Wrapper for Error
88#[derive(Debug)]
89pub enum RegionError {
90    /// IOError
91    IOError(std::io::Error),
92    /// ParseIntError
93    ParseError(ParseIntError),
94    /// Message
95    Message(String),
96}
97
98impl fmt::Display for RegionError {
99    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100        match self {
101            RegionError::IOError(err) => write!(f, "IOError: {}", err),
102            RegionError::ParseError(err) => write!(f, "ParseError: {}", err),
103            RegionError::Message(msg) => write!(f, "Error: {}", msg),
104        }
105    }
106}
107
108impl std::error::Error for RegionError {}