Просмотр исходного кода

Add a Config struct following the builder pattern to idna

Anthony Ramine 7 лет назад
Родитель
Сommit
667c89646a
1 измененных файлов с 86 добавлено и 43 удалено
  1. 86 43
      idna/src/uts46.rs

+ 86 - 43
idna/src/uts46.rs

@@ -353,6 +353,90 @@ fn processing(domain: &str, flags: Flags, errors: &mut Vec<Error>) -> String {
     validated
 }
 
+#[derive(Clone, Copy)]
+pub struct Config {
+    flags: Flags,
+}
+
+impl From<Flags> for Config {
+    #[inline]
+    fn from(flags: Flags) -> Self {
+        Self { flags }
+    }
+}
+
+impl Config {
+    #[inline]
+    pub fn use_std3_ascii_rules(mut self, value: bool) -> Self {
+        self.flags.use_std3_ascii_rules = value;
+        self
+    }
+
+    #[inline]
+    pub fn transitional_processing(mut self, value: bool) -> Self {
+        self.flags.transitional_processing = value;
+        self
+    }
+
+    #[inline]
+    pub fn verify_dns_length(mut self, value: bool) -> Self {
+        self.flags.verify_dns_length = value;
+        self
+    }
+
+    /// http://www.unicode.org/reports/tr46/#ToASCII
+    pub fn to_ascii(self, domain: &str) -> Result<String, Errors> {
+        let mut errors = Vec::new();
+        let mut result = String::new();
+        let mut first = true;
+        for label in processing(domain, self.flags, &mut errors).split('.') {
+            if !first {
+                result.push('.');
+            }
+            first = false;
+            if label.is_ascii() {
+                result.push_str(label);
+            } else {
+                match punycode::encode_str(label) {
+                    Some(x) => {
+                        result.push_str(PUNYCODE_PREFIX);
+                        result.push_str(&x);
+                    },
+                    None => errors.push(Error::PunycodeError)
+                }
+            }
+        }
+
+        if self.flags.verify_dns_length {
+            let domain = if result.ends_with(".") { &result[..result.len()-1] } else { &*result };
+            if domain.len() < 1 || domain.split('.').any(|label| label.len() < 1) {
+                errors.push(Error::TooShortForDns)
+            }
+            if domain.len() > 253 || domain.split('.').any(|label| label.len() > 63) {
+                errors.push(Error::TooLongForDns)
+            }
+        }
+        if errors.is_empty() {
+            Ok(result)
+        } else {
+            Err(Errors(errors))
+        }
+    }
+
+    /// http://www.unicode.org/reports/tr46/#ToUnicode
+    pub fn to_unicode(self, domain: &str) -> (String, Result<(), Errors>) {
+        let mut errors = Vec::new();
+        let domain = processing(domain, self.flags, &mut errors);
+        let errors = if errors.is_empty() {
+            Ok(())
+        } else {
+            Err(Errors(errors))
+        };
+        (domain, errors)
+    }
+
+}
+
 #[derive(Copy, Clone)]
 pub struct Flags {
    pub use_std3_ascii_rules: bool,
@@ -380,41 +464,7 @@ pub struct Errors(Vec<Error>);
 
 /// http://www.unicode.org/reports/tr46/#ToASCII
 pub fn to_ascii(domain: &str, flags: Flags) -> Result<String, Errors> {
-    let mut errors = Vec::new();
-    let mut result = String::new();
-    let mut first = true;
-    for label in processing(domain, flags, &mut errors).split('.') {
-        if !first {
-            result.push('.');
-        }
-        first = false;
-        if label.is_ascii() {
-            result.push_str(label);
-        } else {
-            match punycode::encode_str(label) {
-                Some(x) => {
-                    result.push_str(PUNYCODE_PREFIX);
-                    result.push_str(&x);
-                },
-                None => errors.push(Error::PunycodeError)
-            }
-        }
-    }
-
-    if flags.verify_dns_length {
-        let domain = if result.ends_with(".") { &result[..result.len()-1]  } else { &*result };
-        if domain.len() < 1 || domain.split('.').any(|label| label.len() < 1) {
-            errors.push(Error::TooShortForDns)
-        }
-        if domain.len() > 253 || domain.split('.').any(|label| label.len() > 63) {
-            errors.push(Error::TooLongForDns)
-        }
-    }
-    if errors.is_empty() {
-        Ok(result)
-    } else {
-        Err(Errors(errors))
-    }
+    Config::from(flags).to_ascii(domain)
 }
 
 /// http://www.unicode.org/reports/tr46/#ToUnicode
@@ -422,12 +472,5 @@ pub fn to_ascii(domain: &str, flags: Flags) -> Result<String, Errors> {
 /// Only `use_std3_ascii_rules` is used in `flags`.
 pub fn to_unicode(domain: &str, mut flags: Flags) -> (String, Result<(), Errors>) {
     flags.transitional_processing = false;
-    let mut errors = Vec::new();
-    let domain = processing(domain, flags, &mut errors);
-    let errors = if errors.is_empty() {
-        Ok(())
-    } else {
-        Err(Errors(errors))
-    };
-    (domain, errors)
+    Config::from(flags).to_unicode(domain)
 }