Skip to main content

wedeo_format/
protocol.rs

1use wedeo_core::error::Result;
2
3use crate::io::IoContext;
4
5/// Protocol trait for URL-based I/O.
6pub trait Protocol: Send + Sync {
7    fn name(&self) -> &'static str;
8    fn open(&self, url: &str, flags: ProtocolFlags) -> Result<Box<dyn IoContext>>;
9}
10
11/// Protocol open flags.
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct ProtocolFlags {
14    pub read: bool,
15    pub write: bool,
16}
17
18impl ProtocolFlags {
19    pub const READ: Self = Self {
20        read: true,
21        write: false,
22    };
23    pub const WRITE: Self = Self {
24        read: false,
25        write: true,
26    };
27    pub const READ_WRITE: Self = Self {
28        read: true,
29        write: true,
30    };
31}
32
33inventory::collect!(&'static dyn Protocol);
34
35/// Open a URL using the registered protocol handlers.
36pub fn open_url(url: &str, flags: ProtocolFlags) -> Result<Box<dyn IoContext>> {
37    // Extract scheme from URL
38    let scheme = url.find("://").map(|i| &url[..i]).unwrap_or("file");
39
40    for proto in inventory::iter::<&'static dyn Protocol>() {
41        if proto.name() == scheme {
42            return proto.open(url, flags);
43        }
44    }
45
46    // Default: try as file path
47    if flags.write {
48        Ok(Box::new(crate::io::FileIo::create(url)?))
49    } else {
50        Ok(Box::new(crate::io::FileIo::open(url)?))
51    }
52}