Skip to main content

lindera_dictionary/
decompress.rs

1use std::{io::Read, str::FromStr};
2
3use flate2::read::{DeflateDecoder, GzDecoder, ZlibDecoder};
4use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
5use serde::{Deserialize, Serialize};
6use strum::IntoEnumIterator;
7use strum_macros::EnumIter;
8
9use crate::error::{LinderaError, LinderaErrorKind};
10
11#[derive(
12    Debug,
13    Clone,
14    EnumIter,
15    Copy,
16    PartialEq,
17    Eq,
18    Serialize,
19    Deserialize,
20    Archive,
21    RkyvSerialize,
22    RkyvDeserialize,
23)]
24#[repr(u32)] // explicit representation for consistency
25#[serde(rename_all = "lowercase")]
26pub enum Algorithm {
27    Deflate = 0,
28    Zlib = 1,
29    Gzip = 2,
30    Raw = 3,
31}
32
33impl Algorithm {
34    pub fn variants() -> Vec<Algorithm> {
35        Algorithm::iter().collect::<Vec<_>>()
36    }
37
38    pub fn as_str(&self) -> &str {
39        match self {
40            Algorithm::Deflate => "deflate",
41            Algorithm::Zlib => "zlib",
42            Algorithm::Gzip => "gzip",
43            Algorithm::Raw => "raw",
44        }
45    }
46}
47
48impl FromStr for Algorithm {
49    type Err = LinderaError;
50    fn from_str(input: &str) -> Result<Algorithm, Self::Err> {
51        match input {
52            "deflate" => Ok(Algorithm::Deflate),
53            "zlib" => Ok(Algorithm::Zlib),
54            "gzip" => Ok(Algorithm::Gzip),
55            "raw" => Ok(Algorithm::Raw),
56            _ => Err(LinderaErrorKind::Algorithm
57                .with_error(anyhow::anyhow!("Invalid algorithm: {input}"))),
58        }
59    }
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize, Archive, RkyvSerialize, RkyvDeserialize)]
63
64pub struct CompressedData {
65    pub algorithm: Algorithm,
66    pub data: Vec<u8>,
67}
68
69impl CompressedData {
70    pub fn new(algorithm: Algorithm, data: Vec<u8>) -> Self {
71        CompressedData { algorithm, data }
72    }
73}
74
75pub fn decompress(data: CompressedData) -> anyhow::Result<Vec<u8>> {
76    match data.algorithm {
77        Algorithm::Deflate => {
78            let mut decoder = DeflateDecoder::new(data.data.as_slice());
79            let mut output_data = Vec::new();
80            decoder.read_to_end(&mut output_data)?;
81            Ok(output_data)
82        }
83        Algorithm::Zlib => {
84            let mut decoder = ZlibDecoder::new(data.data.as_slice());
85            let mut output_data = Vec::new();
86            decoder.read_to_end(&mut output_data)?;
87            Ok(output_data)
88        }
89        Algorithm::Gzip => {
90            let mut decoder = GzDecoder::new(data.data.as_slice());
91            let mut output_data = Vec::new();
92            decoder.read_to_end(&mut output_data)?;
93            Ok(output_data)
94        }
95        Algorithm::Raw => Ok(data.data),
96    }
97}