oxidation_bencode 0.2.0

A bencoding library, made for Oxidation.
Documentation
//! An integer, encoded using the 
//! [Bencoding](http://bittorrent.org/beps/bep_0003.html#bencoding) format.
//! 
//! This module contains the [`BencodeInteger`] type, and related error types.
//!
//! [`BencodeInteger`]: struct.BencodeInteger.html


use bencode::Bencodable;
use bencode::BencodeError;

/// An integer, encoded using the 
/// [Bencoding](http://bittorrent.org/beps/bep_0003.html#bencoding) format.
pub struct BencodeInteger
{
    /// The integer encoded by the bencoded object.
    pub integer: u64
}

impl Bencodable<u64> for BencodeInteger
{
    /// Converts a BencodeInteger object into a bencoded string,
    /// in the `i<integer>e` format.
    ///
    /// # Examples
    ///
    /// ```
    /// use oxidation_bencode::bencode::Bencodable;
    /// use oxidation_bencode::integer::BencodeInteger;
    ///
    /// let origString = "i1337e";
    /// let bi = BencodeInteger::from_bencode_string(origString).unwrap();
    /// 
    /// assert_eq!(bi.to_bencode_string(), "i1337e");
    /// ```
    fn to_bencode_string(&self) -> String
    {
        let int = self.integer.to_string();
        let mut final_string = String::new();

        final_string.push('i');
        final_string.push_str(&int);
        final_string.push('e');

        final_string
    }

    /// Converts a bencoded integer into a [`BencodeInteger`]
    /// object.
    ///
    /// # Examples
    ///
    /// ```
    /// use oxidation_bencode::bencode::Bencodable;
    /// use oxidation_bencode::integer::BencodeInteger;
    ///
    /// // Valid Integer
    /// let orig_string = "i1337e";
    /// let bi = BencodeInteger::from_bencode_string(orig_string).unwrap();
    /// 
    /// assert_eq!(bi.extract_content(), 1337);
    ///
    /// // Invalid Integer
    /// let orig_string = "i03e";
    /// let bi = BencodeInteger::from_bencode_string(orig_string);
    /// 
    /// assert!(bi.is_err());
    /// ```
    /// [`BencodeInteger`]: struct.BencodeInteger.html
    fn from_bencode_string(str: &'static str) -> Result<BencodeInteger, BencodeError> {
        if !str.starts_with("i") || !str.ends_with("e") {
            Err(BencodeError::ParseError("integer string is not delimited correctly"))
        } else {

            let stripped_string = str.trim_matches(|c| c == 'i' || c == 'e');

            if (stripped_string.starts_with("0") && stripped_string.chars().count() != 1) || stripped_string.starts_with("-0") {
                Err(BencodeError::ParseError("integer is incorrectly formatted with leading zero"))
            } else {

                let final_integer = u64::from_str_radix(stripped_string, 10);

                if final_integer.is_err() {
                    Err(BencodeError::ParseError("integer string could not be converted into a number"))
                } else {
                    
                    Ok(BencodeInteger {
                        integer: final_integer.unwrap()
                    })
                }
            }
        }
    }

    /// Extracts the contents of a [`BencodeInteger`] and returns them
    /// as a [`u64`].
    ///
    /// #Examples
    /// 
    /// ```
    /// use oxidation_bencode::bencode::Bencodable;
    /// use oxidation_bencode::integer::BencodeInteger;
    ///
    /// let bcoded_int = BencodeInteger::from_bencode_string("i1337e").unwrap();
    ///
    /// let conv_int = bcoded_int.extract_content();
    ///
    /// assert_eq!(conv_int, 1337);
    /// ```
    ///
    /// [`u64`]: https://doc.rust-lang.org/std/primitive.u64.html
    /// [`BencodeInteger`]: struct.BencodeInteger.html
    fn extract_content(&self) -> u64
    {
        self.integer
    }
}