From d15f9bd162b1f44c43df4c0dd74a29a6894e44ec Mon Sep 17 00:00:00 2001
From: Sam Rijs <srijs@airpost.net>
Date: Tue, 4 Jul 2017 13:36:42 +0200
Subject: [PATCH] Improve best-case performance for to_camel_case

---
 src/lib.rs                 | 14 ++++++++------
 src/macros/input_object.rs |  2 +-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index daffddeb..1ad76b71 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -203,6 +203,8 @@ extern crate serde;
 
 #[cfg(any(feature="iron-handlers", feature="rocket-handlers"))] extern crate serde_json;
 
+use std::borrow::Cow;
+
 #[macro_use] mod macros;
 mod ast;
 pub mod parser;
@@ -296,22 +298,22 @@ impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
 }
 
 #[doc(hidden)]
-pub fn to_camel_case(s: &str) -> String {
-    let mut dest = String::new();
+pub fn to_camel_case<'a>(s: &'a str) -> Cow<'a, str> {
+    let mut dest = Cow::Borrowed(s);
 
     for (i, part) in s.split('_').enumerate() {
         if i > 0 && part.len() == 1 {
-            dest.push_str(&part.to_uppercase());
+            dest += Cow::Owned(part.to_uppercase());
         }
         else if i > 0 && part.len() > 1 {
             let first = part.chars().next().unwrap().to_uppercase().collect::<String>();
             let second = &part[1..];
 
-            dest.push_str(&first);
-            dest.push_str(second);
+            dest += Cow::Owned(first);
+            dest += second;
         }
         else if i == 0 {
-            dest.push_str(part);
+            dest = Cow::Borrowed(part);
         }
     }
 
diff --git a/src/macros/input_object.rs b/src/macros/input_object.rs
index 9bccac99..265750ee 100644
--- a/src/macros/input_object.rs
+++ b/src/macros/input_object.rs
@@ -64,7 +64,7 @@ macro_rules! graphql_input_object {
     ) => {
         Some($name {
             $( $field_name: {
-                let n: String = $crate::to_camel_case(stringify!($field_name));
+                let n = $crate::to_camel_case(stringify!($field_name));
                 let v: Option<&&$crate::InputValue> = $var.get(&n[..]);
 
                 match v {