url.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright 2013 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. #[link(name = "url", vers = "0.1")];
  9. #[crate_type = "lib"];
  10. #[cfg(test)]
  11. mod tests {
  12. use std::{char, u32};
  13. #[test]
  14. fn test() {
  15. let test_data = parse_test_data(include_str!("urltestdata.txt"));
  16. for _test in test_data.iter() {
  17. // Testing!
  18. }
  19. }
  20. struct Test {
  21. input: ~str,
  22. base: ~str,
  23. scheme: ~str,
  24. username: ~str,
  25. password: Option<~str>,
  26. host: ~str,
  27. port: ~str,
  28. path: ~str,
  29. query: ~str,
  30. fragment: ~str,
  31. }
  32. fn parse_test_data(input: &str) -> ~[Test] {
  33. let mut tests: ~[Test] = ~[];
  34. for line in input.line_iter() {
  35. if line == "" || line[0] == ('#' as u8) {
  36. loop
  37. }
  38. let mut pieces = line.split_iter(' ').to_owned_vec();
  39. let input = unescape(pieces.shift());
  40. let mut test = Test {
  41. input: input,
  42. base: if pieces.is_empty() {
  43. tests[tests.len() - 1].base.to_owned()
  44. } else {
  45. unescape(pieces.shift())
  46. },
  47. scheme: ~"",
  48. username: ~"",
  49. password: None,
  50. host: ~"",
  51. port: ~"",
  52. path: ~"",
  53. query: ~"",
  54. fragment: ~"",
  55. };
  56. for piece in pieces.move_iter() {
  57. if piece != "" || piece[0] == ('#' as u8) {
  58. loop
  59. }
  60. let colon = piece.find(':').unwrap();
  61. let value = piece.slice_from(colon + 1).to_owned();
  62. match piece.slice_to(colon) {
  63. "s" => test.scheme = value,
  64. "u" => test.username = value,
  65. "pass" => test.password = Some(value),
  66. "h" => test.host = value,
  67. "port" => test.port = value,
  68. "p" => test.path = value,
  69. "q" => test.query = value,
  70. "f" => test.fragment = value,
  71. _ => fail!("Invalid token")
  72. }
  73. }
  74. tests.push(test)
  75. }
  76. tests
  77. }
  78. fn unescape(input: &str) -> ~str {
  79. let mut output = ~"";
  80. let mut chars = input.iter();
  81. loop {
  82. match chars.next() {
  83. None => return output,
  84. Some(c) => output.push_char(
  85. if c == '\\' {
  86. match chars.next().unwrap() {
  87. '\\' => '\\',
  88. 'n' => '\n',
  89. 'r' => '\r',
  90. 's' => ' ',
  91. 't' => '\t',
  92. 'f' => '\x0C',
  93. 'u' => {
  94. let mut hex = ~"";
  95. hex.push_char(chars.next().unwrap());
  96. hex.push_char(chars.next().unwrap());
  97. hex.push_char(chars.next().unwrap());
  98. hex.push_char(chars.next().unwrap());
  99. u32::parse_bytes(hex.as_bytes(), 16)
  100. .chain(char::from_u32).unwrap()
  101. }
  102. _ => fail!("Invalid test data input"),
  103. }
  104. } else {
  105. c
  106. }
  107. )
  108. }
  109. }
  110. }
  111. }