diff --git a/src/schema/document.rs b/src/schema/document.rs index 5c542bebf..253c38081 100644 --- a/src/schema/document.rs +++ b/src/schema/document.rs @@ -76,9 +76,7 @@ impl Document { /// Adding a facet to the document. pub fn add_facet(&mut self, field: Field, path: F) - where - Facet: From, - { + where Facet: From { let facet = Facet::from(path); let value = Value::Facet(facet); self.add_field_value(field, value); diff --git a/src/schema/schema.rs b/src/schema/schema.rs index 0884ef71b..3b7fd22d0 100644 --- a/src/schema/schema.rs +++ b/src/schema/schema.rs @@ -619,12 +619,14 @@ mod tests { schema_builder.add_text_field("title", TEXT); schema_builder.add_text_field("author", STRING); schema_builder.add_u64_field("count", count_options); + schema_builder.add_ip_addr_field("ip", FAST | STORED); schema_builder.add_bool_field("is_read", is_read_options); let schema = schema_builder.build(); let doc_json = r#"{ "title": "my title", "author": "fulmicoton", "count": 4, + "ip": "127.0.0.1", "is_read": true }"#; let doc = schema.parse_document(doc_json).unwrap(); @@ -633,6 +635,39 @@ mod tests { assert_eq!(doc, doc_serdeser); } + #[test] + pub fn test_document_to_ipv4_json() { + let mut schema_builder = Schema::builder(); + schema_builder.add_ip_addr_field("ip", FAST | STORED); + let schema = schema_builder.build(); + + // IpV4 loopback + let doc_json = r#"{ + "ip": "127.0.0.1" + }"#; + let doc = schema.parse_document(doc_json).unwrap(); + let value: serde_json::Value = serde_json::from_str(&schema.to_json(&doc)).unwrap(); + assert_eq!(value["ip"][0], "127.0.0.1"); + + // Special case IpV6 loopback. We don't want to map that to IPv4 + let doc_json = r#"{ + "ip": "::1" + }"#; + let doc = schema.parse_document(doc_json).unwrap(); + + let value: serde_json::Value = serde_json::from_str(&schema.to_json(&doc)).unwrap(); + assert_eq!(value["ip"][0], "::1"); + + // testing ip address of every router in the world + let doc_json = r#"{ + "ip": "192.168.0.1" + }"#; + let doc = schema.parse_document(doc_json).unwrap(); + + let value: serde_json::Value = serde_json::from_str(&schema.to_json(&doc)).unwrap(); + assert_eq!(value["ip"][0], "192.168.0.1"); + } + #[test] pub fn test_document_from_nameddoc() { let mut schema_builder = Schema::builder(); diff --git a/src/schema/value.rs b/src/schema/value.rs index c863f0302..a92e093fb 100644 --- a/src/schema/value.rs +++ b/src/schema/value.rs @@ -41,9 +41,7 @@ impl Eq for Value {} impl Serialize for Value { fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { + where S: Serializer { match *self { Value::Str(ref v) => serializer.serialize_str(v), Value::PreTokStr(ref v) => v.serialize(serializer), @@ -55,16 +53,21 @@ impl Serialize for Value { Value::Facet(ref facet) => facet.serialize(serializer), Value::Bytes(ref bytes) => serializer.serialize_bytes(bytes), Value::JsonObject(ref obj) => obj.serialize(serializer), - Value::IpAddr(ref obj) => obj.serialize(serializer), + Value::IpAddr(ref obj) => { + // Ensure IpV4 addresses get serialized as IpV4, but excluding IpV6 loopback. + if let Some(ip_v4) = obj.to_ipv4_mapped() { + ip_v4.serialize(serializer) + } else { + obj.serialize(serializer) + } + } } } } impl<'de> Deserialize<'de> for Value { fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { + where D: Deserializer<'de> { struct ValueVisitor; impl<'de> Visitor<'de> for ValueVisitor {