summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/introduction.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/examples/introduction.rs b/examples/introduction.rs
new file mode 100644
index 0000000..9d949b4
--- /dev/null
+++ b/examples/introduction.rs
@@ -0,0 +1,131 @@
+extern crate csv;
+extern crate rand;
+extern crate serde;
+#[macro_use]
+extern crate serde_derive;
+extern crate serde_qs as qs;
+extern crate serde_urlencoded as urlencoded;
+
+use rand::Rng;
+use std::collections::HashMap;
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+struct Address {
+ city: String,
+ postcode: String,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+struct QueryParams {
+ id: u8,
+ name: String,
+ address: Address,
+ phone: u32,
+ user_ids: Vec<u8>,
+}
+
+
+fn main() {
+ // Encodes as:
+ // "user_ids%5B3%5D=4&user_ids%5B2%5D=3&address%5Bcity%5D=Carrot+City&\
+ // id=42&address%5Bpostcode%5D=12345&name=Acme&user_ids%5B0%5D=1&\
+ // phone=12345&user_ids%5B1%5D=2"
+ let example_params = QueryParams {
+ id: 42,
+ name: "Acme".to_string(),
+ phone: 12345,
+ address: Address {
+ city: "Carrot City".to_string(),
+ postcode: "12345".to_string(),
+ },
+ user_ids: vec!(1,2,3,4),
+ };
+
+ // Naive approach: manually parameters in a map. Painful.
+ let mut map = HashMap::<&str, &str>::new();
+ map.insert("id", "42");
+ map.insert("name", "Acme");
+ map.insert("phone", "12345");
+ map.insert("address[city]", "Carrot City");
+ map.insert("address[postcode]", "12345");
+ map.insert("user_ids[0]", "1");
+ map.insert("user_ids[1]", "2");
+ map.insert("user_ids[2]", "3");
+ map.insert("user_ids[3]", "4");
+
+ // Note this will be in some random order due to ordering of keys in map.
+ let encoded = qs::to_string(&map).unwrap();
+ println!("`serde_qs` to_string for map:\n\t{}", encoded);
+
+ // In this form, can also simply use `serde_urlencoded`:
+ let encoded = urlencoded::to_string(&map).unwrap();
+ println!("`serde_urlencoded` to_string for map:\n\t{}", encoded);
+
+ // Given this encoded string, you can recover the original map
+ // as a list of pairs using serde_urlencoded:
+ let pairs: Vec<(String, String)> = urlencoded::from_str(&encoded).unwrap();
+ println!("`serde_urlencoded` from_str to pairs:\n\t{:?}", pairs);
+
+ // However, the best way is to use serde_qs to deserialize the entire thing
+ // into a struct:
+ let params: QueryParams = qs::from_str(&encoded).unwrap();
+ assert_eq!(params, example_params);
+ println!("`serde_qs` from_str to struct:\n\t{:?}", params);
+
+ // Similarly, we can serialize this structure using `serde_qs`:
+ let encoded = qs::to_string(&params).unwrap();
+ println!("`serde_qs` to_string for struct:\n\t{:?}", encoded);
+
+ // One nice feature is that this gives deterministic encodings:
+ let encoded2 = qs::to_string(&params).unwrap();
+ assert_eq!(encoded, encoded2);
+
+ // An advantage of `serde_qs` for deserializing, is that it is robust against
+ // different orderings of inputs:
+
+ let mut inputs = vec!["id=42",
+ "name=Acme",
+ "phone=12345",
+ "address[city]=Carrot+City",
+ "address[postcode]=12345",
+ "user_ids[0]=1",
+ "user_ids[1]=2",
+ "user_ids[2]=3",
+ "user_ids[3]=4"
+ ];
+
+ let mut rng = rand::thread_rng();
+ for _ in 0..10 {
+ let mut acc = String::new();
+ rng.shuffle(&mut inputs);
+ for input in &inputs {
+ acc += input;
+ acc += "&";
+ }
+ // remove trailing character
+ acc.pop();
+ let params: QueryParams = qs::from_str(&acc).unwrap();
+ assert_eq!(params, example_params);
+ }
+
+ // By default, `serde_qs` uses arrays with indices to denote position.
+ // However, if omitted, will use input order:
+ let encoded = "id=42&name=Acme&phone=12345&address[city]=Carrot+City&\
+ address[postcode]=12345&\
+ user_ids[]=1&\
+ user_ids[]=2&\
+ user_ids[]=3&\
+ user_ids[]=4";
+ let params: QueryParams = qs::from_str(encoded).unwrap();
+ assert_eq!(params, example_params);
+
+ // Indices do not necessarily need to be continuous:
+ let encoded = "id=42&name=Acme&phone=12345&address[city]=Carrot+City&\
+ address[postcode]=12345&\
+ user_ids[1]=2&\
+ user_ids[0]=1&\
+ user_ids[12]=3&\
+ user_ids[512]=4";
+ let params: QueryParams = qs::from_str(encoded).unwrap();
+ assert_eq!(params, example_params);
+} \ No newline at end of file