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
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
pub mod server;
mod handler;
mod content;
mod catcher;
mod pick_port;
pub mod error;
pub mod http;
pub mod routing;
pub mod depot;
pub mod logging;

// #[macro_use]
extern crate serde;
// #[macro_use]
// extern crate serde_derive;
// #[macro_use]
// extern crate serde_json;
// #[macro_use]
// extern crate mime;
#[macro_use]
extern crate slog;
#[macro_use]
extern crate pin_utils;
#[macro_use]
extern crate futures_util;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;

pub use crate::content::Content;
pub use crate::http::{Request, Response};
pub use crate::server::{Server, ServerConfig};
pub use crate::handler::Handler;
pub use crate::routing::Router;
pub use crate::catcher::{Catcher, CatcherImpl};
pub use crate::error::Error;
pub use crate::depot::Depot;
pub use salvo_macros::fn_handler;

use std::ops::{Bound, RangeBounds};

pub mod prelude {
    pub use crate::server::{Server, ServerConfig};
    pub use crate::routing::Router;
    pub use crate::depot::Depot;
    pub use crate::http::{Request, Response};
    pub use crate::Handler;
    pub use crate::logging;
    pub use std::sync::Arc;
    pub use salvo_macros::fn_handler;
    pub use async_trait::async_trait;
}

trait StringUtils {
    fn substring(&self, start: usize, len: usize) -> &str;
    fn slice(&self, range: impl RangeBounds<usize>) -> &str;
}

impl StringUtils for str {
    fn substring(&self, start: usize, len: usize) -> &str {
        let mut char_pos = 0;
        let mut byte_start = 0;
        let mut it = self.chars();
        loop {
            if char_pos == start { break; }
            if let Some(c) = it.next() {
                char_pos += 1;
                byte_start += c.len_utf8();
            }
            else { break; }
        }
        char_pos = 0;
        let mut byte_end = byte_start;
        loop {
            if char_pos == len { break; }
            if let Some(c) = it.next() {
                char_pos += 1;
                byte_end += c.len_utf8();
            }
            else { break; }
        }
        &self[byte_start..byte_end]
    }
    fn slice(&self, range: impl RangeBounds<usize>) -> &str {
        let start = match range.start_bound() {
            Bound::Included(bound) | Bound::Excluded(bound) => *bound,
            Bound::Unbounded => 0,
        };
        let len = match range.end_bound() {
            Bound::Included(bound) => *bound + 1,
            Bound::Excluded(bound) => *bound,
            Bound::Unbounded => self.len(),
        } - start;
        self.substring(start, len)
    }
}

#[derive(Clone)]
enum _Protocol {
    Http,
    Https,
}

/// Protocol used to serve content.
#[derive(Clone)]
pub struct Protocol(_Protocol);

impl Protocol {
    /// Plaintext HTTP/1
    pub fn http() -> Protocol {
        Protocol(_Protocol::Http)
    }

    /// HTTP/1 over SSL/TLS
    pub fn https() -> Protocol {
        Protocol(_Protocol::Https)
    }

    /// Returns the name used for this protocol in a URI's scheme part.
    pub fn name(&self) -> &str {
        match self.0 {
            _Protocol::Http => "http",
            _Protocol::Https => "https",
        }
    }
}