encoding.rs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. #[derive(Copy, Clone)]
  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)
  36. .ok()
  37. .and_then(encoding_from_whatwg_label)
  38. .map(EncodingOverride::from_encoding)
  39. }
  40. pub fn is_utf8(&self) -> bool {
  41. self.encoding.is_none()
  42. }
  43. pub fn decode(&self, input: &[u8]) -> String {
  44. match self.encoding {
  45. Some(encoding) => encoding.decode(input, DecoderTrap::Replace).unwrap(),
  46. None => String::from_utf8_lossy(input).to_string(),
  47. }
  48. }
  49. pub fn encode<'a>(&self, input: &'a str) -> Cow<'a, [u8]> {
  50. match self.encoding {
  51. Some(encoding) => Cow::Owned(
  52. encoding.encode(input, EncoderTrap::NcrEscape).unwrap()),
  53. None => Cow::Borrowed(input.as_bytes()), // UTF-8
  54. }
  55. }
  56. }
  57. #[cfg(not(feature = "query_encoding"))]
  58. #[derive(Copy, Clone)]
  59. pub struct EncodingOverride;
  60. #[cfg(not(feature = "query_encoding"))]
  61. impl EncodingOverride {
  62. pub fn utf8() -> EncodingOverride {
  63. EncodingOverride
  64. }
  65. pub fn lookup(_label: &[u8]) -> Option<EncodingOverride> {
  66. None
  67. }
  68. pub fn is_utf8(&self) -> bool {
  69. true
  70. }
  71. pub fn decode(&self, input: &[u8]) -> String {
  72. String::from_utf8_lossy(input).into_owned()
  73. }
  74. pub fn encode<'a>(&self, input: &'a str) -> Cow<'a, [u8]> {
  75. Cow::Borrowed(input.as_bytes())
  76. }
  77. }