#[derive(Debug, PartialEq)]
pub struct BearerAuthorizationHeader<'a>(pub &'a str);

#[derive(Debug, PartialEq)]
pub enum BearerAuthorizationParseError {
    NotBearer,
}

impl<'a> TryFrom<&'a str> for BearerAuthorizationHeader<'a> {
    type Error = BearerAuthorizationParseError;

    fn try_from(value: &'a str) -> Result<Self, Self::Error> {
        value
            .trim()
            .strip_prefix("Bearer ")
            .map(BearerAuthorizationHeader)
            .ok_or(BearerAuthorizationParseError::NotBearer)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_try_from_valid() {
        let result = BearerAuthorizationHeader::try_from("Bearer bearervalue");

        assert_eq!(result, Ok(BearerAuthorizationHeader("bearervalue")));
    }

    #[test]
    fn test_try_from_valid_padding() {
        let result = BearerAuthorizationHeader::try_from("   Bearer bearervalue  ");

        assert_eq!(result, Ok(BearerAuthorizationHeader("bearervalue")));
    }

    #[test]
    fn test_try_from_invalid() {
        let result = BearerAuthorizationHeader::try_from(
            "this-is/a-hmac:5745fd9c0640945e8b744def34ebafff9e9f6846",
        );

        assert_eq!(result, Err(BearerAuthorizationParseError::NotBearer));
    }
}
