https://plantuml.com/class-diagram
@startuml
package web_framework_lib <<Node>> {
    namespace models {
        class Transaction
            Transaction : req: Request
            Transaction : res: Response
            Transaction : resolved: bool
            Transaction : pub fn new(req: Request, res: Response) -> Self
            Transaction : pub fn resolve(&mut self) -> Result<(), &str>
            Transaction : pub fn req(&self) -> &Request
            Transaction : pub fn res(&self) -> &Response
            Transaction : pub fn req_mut(&mut self) -> &mut Request
            Transaction : pub fn res_mut(&mut self) -> &mut Response
            Transaction : pub fn resolved(&self) -> bool
            Transaction : pub fn set_resolved(&mut self, resolved: bool)

        class Request
            Transaction "1" *-l- Request : contains

            Request : request_line_data: RequestLineData
            Request : request_headers: RequestHeaders
            Request : stream: TcpStream
            Request : pub fn new(req_str: String, stream: TcpStream) -> Self
            Request : fn req_str_to_header_map(req_str: Vec<&str>) -> HashMap<String, String>
            Request : request_line_data(&self) -> &RequestLineData
            Request : pub fn request_header_map(&self) -> &RequestHeaders
            Request : pub fn stream(&self) -> &TcpStream
            Request : pub fn set_request_line_data(&mut self, request_line_data: RequestLineData)
            Request : pub fn set_request_header_map(&mut self, request_headers: RequestHeaders)
            Request : pub fn set_stream(&mut self, stream: TcpStream)

        class RequestLineData
            Request "1" *-- RequestLineData : contains

            RequestLineData : method: String
            RequestLineData : path: String
            RequestLineData : protocol: String
            RequestLineData : request_queries: Option<RequestQueries>
            RequestLineData : pub fn new(req_str_first_line: &str) -> Self
            RequestLineData : pub fn get_path_cell_by_index_url_encoded(&self, index: usize) -> Option<String>
            RequestLineData : pub fn get_path_cell_by_index_url_decoded(&self, index: usize) -> Option<String>
            RequestLineData : pub fn method(&self) -> &str
            RequestLineData : pub fn protocol(&self) -> &str
            RequestLineData : pub fn path(&self) -> &str
            RequestLineData : pub fn request_queries(&self) -> &Option<RequestQueries>
            RequestLineData : pub fn set_method(&mut self, method: String)
            RequestLineData : pub fn set_path(&mut self, path: String)
            RequestLineData : pub fn set_protocol(&mut self, protocol: String)
            RequestLineData : pub fn set_request_queries(&mut self, request_queries: Option<RequestQueries>)

        class RequestQueries
            RequestLineData "1" *-r- RequestQueries : contains

            RequestQueries : queries: HashMap<String, String>
            RequestQueries : pub fn new_empty() -> Self
            RequestQueries : pub fn new(queries: HashMap<String, String>) -> Self
            RequestQueries : pub fn add_query(&mut self, key: &str, val: &str)
            RequestQueries : pub fn remove_query_and_get_val(&mut self, key: &str) -> Option<String>
            RequestQueries : pub fn remove_query(&mut self, key: &str) -> bool

        class RequestHeaders
            Request "1" *-l- RequestHeaders : contains

            RequestHeaders : headers: HashMap<String, String>
            RequestHeaders : pub fn new_empty() -> Self
            RequestHeaders : pub fn new(headers: HashMap<String, String>) -> Self
            RequestHeaders : pub fn add_header(&mut self, key: &str, val: &str)
            RequestHeaders : pub fn remove_header_and_get_val(&mut self, key: &str) -> Option<String>
            RequestHeaders : pub fn remove_header(&mut self, key: &str) -> bool

        class Response<'a>
            Transaction "1" *-- Response : contains

            Response : protocol: &'a str
            Response : status: u16
            Response : reason_phrase: &'a str
            Response : headers: HashMap<&'a str, String>
            Response : pub fn new(status: u16, reason_phrase: &str) -> Self
            Response : pub fn new_empty() -> Self
            Response : pub fn ok() -> Self
            Response : pub fn not_found() -> Self
            Response : pub fn bad_request(s: &str) -> Self
            Response : pub fn set_body_to_file(&mut self, path_from_public: &str) -> Result<(), Error>
            Response : pub fn add_header(&mut self, key: &'a str, val: String)
            Response : pub fn set_body(&mut self, body: String)
            Response : pub fn set_body_u8(&mut self, body: Vec<u8>)
            Response : pub fn get_as_u8_vec(&mut self) -> Vec<u8>
            Response : pub fn protocol(&self) -> &str
            Response : pub fn status(&self) -> u16
            Response : pub fn reason_phrase(&self) -> &str
            Response : pub fn body(&self) -> &Vec<u8>
            Response : pub fn headers(&self) -> &HashMap<&'a str, String>
            Response : pub fn set_status(&mut self, status: u16) -> &mut Self
            Response : pub fn set_reason_phrase(&mut self, reason_phrase: &'a str) -> &mut Self
    }
    namespace util {
        namespace enums {
            enum HttpMethod {
                GET,
                POST,
                PUT,
                DELETE
            }
            HttpMethod <|.u. proc_macro_derive.EnumFromStr
            HttpMethod <|.u. proc_macro_derive.StrFromEnum
            enum StaticFileExt {
                AAC, ABW, ARC, AVI, AZW, BIN, BMP, BZ, BZ2, CSH, CSS, CSV, DOC, DOCX, EOT, EPUB, GZ, GIF, HTML,
                ICO, ICS, JAR, JPEG, JPG, JS, JSON, JSONLD, MIDI, MJS, MP3, MPEG, MPKG, ODP, ODS, ODT, OGA, OGV,
                OGX, OPUS, OTF, PNG, PDF, PHP, PPT, PPTX, RAR, RTF, SH, SVG, SWF, TAR, TIFF, TS, TTF, TXT, VSD,
                WAV, WEBA, WEBM, WEBP, WOFF, WOFF2, XHTML, XLS, XLSX, XML, XUL, ZIP, THREEGP, THREEG2, SEVENZ,
                IgnoreThisVariant
            }
            StaticFileExt <|.u.... proc_macro_derive.EnumFromStr : (e.g "7z" => StaticFileExt::SEVENZ)
            StaticFileExt <|.u. proc_macro_derive.StrFromEnum : (mime_types [using a csv file pointed to by helper attribute])\n(e.g StaticFileExt::HTML => "text/html")
        }
        class request_parser
        request_parser : pub fn parse_request<'a>(mut tcp_stream: TcpStream, mut buf: [u8; 1024]) -> Transaction<'a>
    }
    namespace request_handling {
        class request_handler
        request_handler : pub fn enter_chain(mut transaction: Transaction, container: Arc<IocContainer>)
        request_handler : fn rule_out_static_resources(transaction: &mut Transaction) -> bool
        request_handler <.. models.Transaction : mutates/resolves
        request_handler <.l. RouteHandlerContainer : provides user implemented handlers
        class RouteHandlerContainer
        RouteHandlerContainer : method_map: HashMap<HttpMethod, HashMap<String, HandlerFunction>>
        RouteHandlerContainer <|.u. di_ioc_lib.Providable
        RouteHandlerContainer : pub fn new() -> Self
        RouteHandlerContainer : pub fn get_match(&self, path: &str, method: &HttpMethod) -> Option<&HandlerFunction>
        RouteHandlerContainer : pub fn insert(&mut self, k: &str, v: HandlerFunction, method: HttpMethod)
    }
}
package proc_macro_derive {
    annotation EnumFromStr
    EnumFromStr : pub fn from_str(s: &str) -> Result<Self, ()>
    annotation StrFromEnum
    StrFromEnum : pub fn to_string(&self) -> String
}
package di_ioc_lib {
    class IocContainer
    IocContainer : providers: HashMap<TypeId, Arc<dyn Any>>
    interface external.Default
    interface external.Send
    interface external.Sync
    IocContainer <|.u. external.Default
    IocContainer <|.u. external.Send
    IocContainer <|.u. external.Sync
    IocContainer : pub fn install_value_provider<TypeProvided: Providable, PROVIDER: 'static + Provider<TypeProvided = TypeProvided>>(&mut self, provider: PROVIDER)
    IocContainer : pub fn install_reference_provider<ReferenceType: Providable, PROVIDER: 'static + ReferenceProvider<RefProvided = ReferenceType>>(&mut self, provider: PROVIDER)
    IocContainer : pub fn get<TypeToGet: Providable>(&self) -> Result<TypeToGet, ProviderError>
    IocContainer : pub fn get_ref<RefToGet: 'static>(&self) -> Result<&RefToGet, ProviderError>
    IocContainer : fn get_id<T: 'static>() -> TypeId
    IocContainer : fn box_provider<T: 'static, P: 'static + Provider<TypeProvided = T>>(provider: P, ) -> Box<dyn Provider<TypeProvided = T>>
    IocContainer : fn box_ref_provider<T: 'static, P: 'static + ReferenceProvider<RefProvided = T>>(provider: P, ) -> Box<dyn ReferenceProvider<RefProvided = T>>
    interface Providable
    Providable : lifetime='static
    interface Provider
    Provider : type TypeProvided: 'static
    Provider : (pub implied) fn provide(&self, container: &IocContainer) -> Result<Self::TypeProvided, String>
    Provider : (pub implied) fn id_of_type_provided(&self) -> TypeId
    interface ReferenceProvider
    ReferenceProvider : type RefProvided: 'static
    ReferenceProvider : (pub implied) fn provide(&self, container: &IocContainer) -> Result<&Self::RefProvided, String>
    ReferenceProvider : (pub implied) fn id_of_reference_provided(&self) -> TypeId
    class external.Arc<T>
    external.Arc <|.. ReferenceProvider
    class external.HashMap<K, V>
    external.HashMap <|.. Providable
    class external.Vec<T>
    external.HashMap <|.. Providable
}




@enduml