encoding.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright 2013-2014 Simon Sapin.
  2. //
  3. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  4. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  5. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  6. // option. This file may not be copied, modified, or distributed
  7. // except according to those terms.
  8. //! Abstraction that conditionally compiles either to rust-encoding,
  9. //! or to only support UTF-8.
  10. #[cfg(feature = "query_encoding")] extern crate encoding;
  11. use std::borrow::Cow;
  12. #[cfg(feature = "query_encoding")] use self::encoding::types::{DecoderTrap, EncoderTrap};
  13. #[cfg(feature = "query_encoding")] use self::encoding::label::encoding_from_whatwg_label;
  14. #[cfg(feature = "query_encoding")] pub use self::encoding::types::EncodingRef;
  15. #[cfg(feature = "query_encoding")]
  16. #[deriving(Copy)]
  17. pub struct EncodingOverride {
  18. /// `None` means UTF-8.
  19. encoding: Option<EncodingRef>
  20. }
  21. #[cfg(feature = "query_encoding")]
  22. impl EncodingOverride {
  23. pub fn from_opt_encoding(encoding: Option<EncodingRef>) -> EncodingOverride {
  24. encoding.map(EncodingOverride::from_encoding).unwrap_or_else(EncodingOverride::utf8)
  25. }
  26. pub fn from_encoding(encoding: EncodingRef) -> EncodingOverride {
  27. EncodingOverride {
  28. encoding: if encoding.name() == "utf-8" { None } else { Some(encoding) }
  29. }
  30. }
  31. pub fn utf8() -> EncodingOverride {
  32. EncodingOverride { encoding: None }
  33. }
  34. pub fn lookup(label: &[u8]) -> Option<EncodingOverride> {
  35. ::std::str::from_utf8(label.as_slice())
  36. .and_then(encoding_from_whatwg_label)
  37. .map(EncodingOverride::from_encoding)
  38. }
  39. pub fn is_utf8(&self) -> bool {
  40. self.encoding.is_none()
  41. }
  42. pub fn decode(&self, input: &[u8]) -> String {
  43. match self.encoding {
  44. Some(encoding) => encoding.decode(input, DecoderTrap::Replace).unwrap(),
  45. None => String::from_utf8_lossy(input).into_string(),
  46. }
  47. }
  48. pub fn encode<'a>(&self, input: &'a str) -> Cow<'a, Vec<u8>, [u8]> {
  49. match self.encoding {
  50. Some(encoding) => Cow::Owned(
  51. encoding.encode(input.as_slice(), EncoderTrap::NcrEscape).unwrap()),
  52. None => Cow::Borrowed(input.as_bytes()), // UTF-8
  53. }
  54. }
  55. }
  56. #[cfg(not(feature = "query_encoding"))]
  57. #[deriving(Copy)]
  58. pub struct EncodingOverride;
  59. #[cfg(not(feature = "query_encoding"))]
  60. impl EncodingOverride {
  61. pub fn utf8() -> EncodingOverride {
  62. EncodingOverride
  63. }
  64. pub fn lookup(_label: &[u8]) -> Option<EncodingOverride> {
  65. None
  66. }
  67. pub fn is_utf8(&self) -> bool {
  68. true
  69. }
  70. pub fn decode(&self, input: &[u8]) -> String {
  71. String::from_utf8_lossy(input).into_string()
  72. }
  73. pub fn encode<'a>(&self, input: &'a str) -> Cow<'a, Vec<u8>, [u8]> {
  74. Cow::Borrowed(input.as_bytes())
  75. }
  76. }