commit 456d59cf0cc01c586536643a6b8730c11cd41be1 Author: Pyfisch Date: Sun Jul 19 14:05:56 2015 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9d37c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..23d6eaa --- /dev/null +++ b/.travis.yml @@ -0,0 +1,29 @@ +language: rust +sudo: false +addons: + apt: + packages: + - libcurl4-openssl-dev + - libelf-dev + - libdw-dev +rust: +- nightly +- beta +- stable +before_script: +- | + pip install 'travis-cargo<0.2' --user && + export PATH=$HOME/.local/bin:$PATH +script: +- | + travis-cargo build && + travis-cargo test && + travis-cargo bench && + travis-cargo --only stable doc +after_success: +- travis-cargo --only stable doc-upload +- travis-cargo coveralls --no-sudo +env: + global: + - TRAVIS_CARGO_NIGHTLY_FEATURE="" + - secure: DDNxNutlRUJWnae6xiRB4uCuscQUMlFP3PY3TSVE+AU2vQSufTinmy/zCajcwCjZt8VSbh9JNIb4vR6h1hhcPANuOk2dy3avtxVXA08USGl9oJSGxuzJB1Gul9I3kXcHoo/IHDMdzSGcGHBkNbWtLtr0MN9fp6XmrSLkxGpNGLM= diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..6403f72 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "charsets" +version = "0.1.0" +authors = ["Pyfisch "] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b1b75fa --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 Pyfisch + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0f34382 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# rust-charsets +[![Build Status](https://travis-ci.org/pyfisch/rust-charsets.svg?branch=master)](https://travis-ci.org/pyfisch/rust-charsets) +[![Coverage Status](https://coveralls.io/repos/pyfisch/rust-charsets/badge.svg)](https://coveralls.io/r/pyfisch/rust-charsets) +[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) +[![crates.io](http://meritbadge.herokuapp.com/rust-charsets)](https://crates.io/crates/rust-charsets) diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..485e111 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,192 @@ +use std::fmt::{self, Display}; +use std::str::FromStr; +use std::ascii::AsciiExt; +use std::error::Error as ErrorTrait; + +use self::Charset::*; + +#[derive(Debug, Eq, PartialEq)] +pub enum Error { + Invalid +} + +impl ErrorTrait for Error { + fn description(&self) -> &str { + return "The given charset is invalid" + } +} + +impl Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.description()) + } +} + +/// Result type used for this library. +pub type Result = ::std::result::Result; + +/// A Mime charset. +/// +/// The string representation is normalised to upper case. +/// +/// See http://www.iana.org/assignments/character-sets/character-sets.xhtml +#[derive(Clone, Debug, Eq, Ord, PartialOrd)] +pub enum Charset{ + /// US ASCII + UsAscii, + /// ISO-8859-1 + Iso88591, + /// ISO-8859-2 + Iso88592, + /// ISO-8859-3 + Iso88593, + /// ISO-8859-4 + Iso88594, + /// ISO-8859-5 + Iso88595, + /// ISO-8859-6 + Iso88596, + /// ISO-8859-7 + Iso88597, + /// ISO-8859-8 + Iso88598, + /// ISO-8859-9 + Iso88599, + /// ISO-8859-10 + Iso885910, + /// Shift_JIS + ShiftJis, + /// EUC-JP + EucJp, + /// ISO-2022-KR + Iso2022Kr, + /// EUC-KR + EucKr, + /// ISO-2022-JP + Iso2022Jp, + /// ISO-2022-JP-2 + Iso2022Jp2, + /// ISO-8859-6-E + Iso88596E, + /// ISO-8859-6-I + Iso88596I, + /// ISO-8859-8-E + Iso88598E, + /// ISO-8859-8-I + Iso88598I, + /// GB2312 + Gb2312, + /// Big5 + Big5, + /// KOI8-R + Koi8R, + /// An arbitrary charset specified as a string + Unregistered(String) +} + +const MAPPING: [(Charset, &'static str); 24] = [ + (UsAscii, "US-ASCII"), + (Iso88591, "ISO-8859-1"), + (Iso88592, "ISO-8859-2"), + (Iso88593, "ISO-8859-3"), + (Iso88594, "ISO-8859-4"), + (Iso88595, "ISO-8859-5"), + (Iso88596, "ISO-8859-6"), + (Iso88597, "ISO-8859-7"), + (Iso88598, "ISO-8859-8"), + (Iso88599, "ISO-8859-9"), + (Iso885910, "ISO-8859-10"), + (ShiftJis, "Shift-JIS"), + (EucJp, "EUC-JP"), + (Iso2022Kr, "ISO-2022-KR"), + (EucKr, "EUC-KR"), + (Iso2022Jp, "ISO-2022-JP"), + (Iso2022Jp2, "ISO-2022-JP-2"), + (Iso88596E, "ISO-8859-6-E"), + (Iso88596I, "ISO-8859-6-I"), + (Iso88598E, "ISO-8859-8-E"), + (Iso88598I, "ISO-8859-8-I"), + (Gb2312, "GB2312"), + (Big5, "5"), + (Koi8R, "KOI8-R") +]; + +impl Charset { + fn name(&self) -> &str { + if let &Unregistered(ref s) = self { + return &s[..] + } + MAPPING.iter() + .find(|&&(ref variant, _)| self == variant) + .map(|&(_, name)| name).unwrap() + } +} + +impl Display for Charset { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.name()) + } +} + +impl FromStr for Charset { + type Err = ::Error; + fn from_str(s: &str) -> ::Result { + Ok(MAPPING.iter() + .find(|&&(_, ref name)| name.eq_ignore_ascii_case(s)) + .map(|&(ref variant, _)| variant.to_owned()) + .unwrap_or(Unregistered(s.to_owned()))) + } +} + +impl PartialEq for Charset { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (&UsAscii, &UsAscii) | + (&Iso88591, &Iso88591) | + (&Iso88592, &Iso88592) | + (&Iso88593, &Iso88593) | + (&Iso88594, &Iso88594) | + (&Iso88595, &Iso88595) | + (&Iso88596, &Iso88596) | + (&Iso88597, &Iso88597) | + (&Iso88598, &Iso88598) | + (&Iso88599, &Iso88599) | + (&Iso885910, &Iso885910) | + (&ShiftJis, &ShiftJis) | + (&EucJp, &EucJp) | + (&Iso2022Kr, &Iso2022Kr) | + (&EucKr, &EucKr) | + (&Iso2022Jp, &Iso2022Jp) | + (&Iso2022Jp2, &Iso2022Jp2) | + (&Iso88596E, &Iso88596E) | + (&Iso88596I, &Iso88596I) | + (&Iso88598E, &Iso88598E) | + (&Iso88598I, &Iso88598I) | + (&Gb2312, &Gb2312) | + (&Big5, &Big5) | + (&Koi8R, &Koi8R) => true, + (&Unregistered(ref s), &Unregistered(ref t)) => s.eq_ignore_ascii_case(t), + _ => false + } + } +} + +#[test] +fn test_parse() { + assert_eq!(UsAscii,"us-ascii".parse().unwrap()); + assert_eq!(UsAscii,"US-Ascii".parse().unwrap()); + assert_eq!(UsAscii,"US-ASCII".parse().unwrap()); + assert_eq!(ShiftJis,"Shift-JIS".parse().unwrap()); + assert_eq!(Unregistered("ABCD".to_owned()),"abcd".parse().unwrap()); +} + +#[test] +fn test_display() { + assert_eq!("US-ASCII", format!("{}", UsAscii)); + assert_eq!("ABCD", format!("{}", Unregistered("ABCD".to_owned()))); +} + +#[test] +fn test_cmp() { + assert_eq!(Unregistered("foobar".to_owned()), Unregistered("FOOBAR".to_owned())); +}