1use crate::error::{Error, Result};
7use std::path::Path;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum Compression {
12 None,
14 Gzip,
16 Bgzip,
18 Zstd,
20}
21
22impl Compression {
23 pub fn from_path<P: AsRef<Path>>(path: P) -> Self {
25 let path = path.as_ref();
26 if let Some(ext) = path.extension() {
27 match ext.to_str() {
28 Some("gz") => Compression::Gzip,
29 Some("bgz") | Some("bgzf") => Compression::Bgzip,
30 Some("zst") => Compression::Zstd,
31 _ => Compression::None,
32 }
33 } else {
34 Compression::None
35 }
36 }
37}
38
39#[derive(Debug, Clone)]
41pub enum FileLocation {
42 Local(String),
44 S3(String),
46 Gcs(String),
48 Azure(String),
50 Http(String),
52}
53
54impl FileLocation {
55 pub fn parse(s: &str) -> Self {
57 if s.starts_with("s3://") {
58 FileLocation::S3(s.to_string())
59 } else if s.starts_with("gs://") {
60 FileLocation::Gcs(s.to_string())
61 } else if s.starts_with("http://") || s.starts_with("https://") {
62 FileLocation::Http(s.to_string())
63 } else if s.starts_with("az://") || s.starts_with("azure://") {
64 FileLocation::Azure(s.to_string())
65 } else {
66 FileLocation::Local(s.to_string())
67 }
68 }
69
70 pub fn is_local(&self) -> bool {
72 matches!(self, FileLocation::Local(_))
73 }
74
75 pub fn is_remote(&self) -> bool {
77 !self.is_local()
78 }
79}
80
81pub struct CloudReader;
83
84impl CloudReader {
85 pub fn open(_location: FileLocation) -> Result<Self> {
87 Err(Error::NotImplemented(
88 "Cloud storage support will be implemented in Phase 1b".to_string(),
89 ))
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_compression_detection() {
99 assert_eq!(
100 Compression::from_path("file.vcf.gz"),
101 Compression::Gzip
102 );
103 assert_eq!(
104 Compression::from_path("file.vcf.bgz"),
105 Compression::Bgzip
106 );
107 assert_eq!(
108 Compression::from_path("file.vcf"),
109 Compression::None
110 );
111 }
112
113 #[test]
114 fn test_file_location_parsing() {
115 assert!(matches!(
116 FileLocation::parse("/local/path/file.vcf"),
117 FileLocation::Local(_)
118 ));
119 assert!(matches!(
120 FileLocation::parse("s3://bucket/file.vcf"),
121 FileLocation::S3(_)
122 ));
123 assert!(matches!(
124 FileLocation::parse("gs://bucket/file.vcf"),
125 FileLocation::Gcs(_)
126 ));
127 }
128}