diff --git a/Cargo.lock b/Cargo.lock
index 79e74add661a882d867407e8797cee4f1997b4fa..63963cf9ef3ee7a7a019f0399957444f51def369 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
 
 [[package]]
 name = "ahash"
-version = "0.8.7"
+version = "0.8.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
+checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
 dependencies = [
  "cfg-if",
  "getrandom",
@@ -27,9 +27,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.79"
+version = "1.0.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
+checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
 
 [[package]]
 name = "autocfg"
@@ -66,9 +66,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bumpalo"
-version = "3.14.0"
+version = "3.15.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
+checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
 
 [[package]]
 name = "bytecount"
@@ -157,9 +157,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.2.2"
+version = "2.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520"
+checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -183,9 +183,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
 
 [[package]]
 name = "js-sys"
-version = "0.3.68"
+version = "0.3.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
+checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -242,9 +242,9 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.20"
+version = "0.4.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
 
 [[package]]
 name = "memchr"
@@ -422,9 +422,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.78"
+version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
 dependencies = [
  "unicode-ident",
 ]
@@ -461,9 +461,9 @@ dependencies = [
 
 [[package]]
 name = "regex-automata"
-version = "0.4.5"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
+checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -478,15 +478,16 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
 
 [[package]]
 name = "ryu"
-version = "1.0.16"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
+checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
 
 [[package]]
 name = "schema-police"
-version = "0.1.0"
+version = "0.1.2"
 dependencies = [
  "jsonschema",
+ "serde",
  "serde_json",
  "utoipa",
 ]
@@ -499,29 +500,29 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
 [[package]]
 name = "serde"
-version = "1.0.196"
+version = "1.0.197"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
+checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.196"
+version = "1.0.197"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
+checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.48",
+ "syn 2.0.53",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.113"
+version = "1.0.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
+checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
 dependencies = [
  "itoa",
  "ryu",
@@ -546,9 +547,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.48"
+version = "2.0.53"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
+checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -614,9 +615,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
 
 [[package]]
 name = "unicode-normalization"
-version = "0.1.22"
+version = "0.1.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
 dependencies = [
  "tinyvec",
 ]
@@ -653,14 +654,14 @@ dependencies = [
  "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn 2.0.48",
+ "syn 2.0.53",
 ]
 
 [[package]]
 name = "uuid"
-version = "1.7.0"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
+checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
 
 [[package]]
 name = "version_check"
@@ -676,9 +677,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.91"
+version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f"
+checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
 dependencies = [
  "cfg-if",
  "wasm-bindgen-macro",
@@ -686,24 +687,24 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.91"
+version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b"
+checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
 dependencies = [
  "bumpalo",
  "log",
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.48",
+ "syn 2.0.53",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.91"
+version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed"
+checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -711,22 +712,22 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.91"
+version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
+checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.48",
+ "syn 2.0.53",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.91"
+version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
+checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
 
 [[package]]
 name = "windows-targets"
@@ -802,5 +803,5 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.48",
+ "syn 2.0.53",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 36b35c237e3c869c032cf8b277e9c847d9809f9b..a3668b6ac748076d8b5c88261a0a9cd8654a71aa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "schema-police"
-version = "0.1.1"
+version = "0.1.2"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -11,3 +11,4 @@ serde_json = "1.0.113"
 
 [dev-dependencies]
 utoipa = "4.2.0"
+serde = { version = "*", features = ["derive"]}
diff --git a/src/lib.rs b/src/lib.rs
index 5d777b86e0a0790ad0221c33df15be44910a1d39..30f8c280784bf42b2408f8f2116fc6e26526cc17 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -18,11 +18,7 @@ pub struct SchemaInspector {
 }
 
 impl SchemaInspector {
-    const PROP: &'static str = "properties";
     const REF: &'static str = "$ref";
-    const AOF: &'static str = "allOf";
-    const OOF: &'static str = "oneOf";
-    const ITM: &'static str = "items";
 
     /// Initialize the `SchemaInspector` using the name of the type provided to the function using the turbofish syntax instead of using a string
     ///
@@ -65,29 +61,17 @@ impl SchemaInspector {
             return Err(InitError::InvalidSchema(None));
         };
         // extract target from schema
-        let Value::Object(mut target) = schemas
+        let mut target = schemas
             .get(target)
             .ok_or_else(|| SchemaNotFound(target.to_owned()))?
-            .to_owned()
-        else {
-            return Err(InitError::InvalidSchema(None));
-        };
+            .to_owned();
         if resolve_refs {
-            // extract properties
-            let Value::Object(mut props) = target
-                .remove(Self::PROP)
-                .ok_or_else(|| InvalidSchema(Some(Self::PROP.to_owned())))?
-            else {
-                return Err(InvalidSchema(Some(Self::PROP.to_owned())));
-            };
-            Self::resolve_references(schemas, &mut props)?;
-            // reinsert resolved properties
-            target.insert(Self::PROP.into(), Value::Object(props));
+            Self::resolve_references(schemas, &mut target)?;
         }
         Ok(Self {
             schema: JSONSchema::options()
                 .with_draft(Draft::Draft202012)
-                .compile(&Value::Object(target))
+                .compile(&target)
                 .map_err(|_| CompileFailure)?,
         })
     }
@@ -95,52 +79,32 @@ impl SchemaInspector {
     /// Replace internal '$ref' references with the correct schemas
     /// The current implementation disregards the paths in the references and only uses the schema names
     /// to retrieve them from the root schemas object
-    fn resolve_references(
-        schemas: &Map<String, Value>,
-        props: &mut Map<String, Value>,
-    ) -> Result<(), InitError> {
-        let to_resolve: Vec<(String, String)> = props
-            .iter()
-            .filter_map(|(key, val)| {
-                Self::extract_ref(val)
-                    .or_else(|| {
-                        // Get the first item of allOf array and get the "$ref" field from that object
-                        val.get(Self::AOF)
-                            .and_then(|aof| aof.get(0).and_then(Self::extract_ref))
-                    })
-                    .map(|schema_name| (key.to_owned(), schema_name.to_owned()))
-            })
-            .collect();
-        // replace the references in props fields with the correct schemas
-        for (field, schema) in &to_resolve {
-            let inner = props.get_mut(field).expect("known field cannot fail");
-            *inner = schemas
-                .get(schema)
-                .ok_or_else(|| InitError::ResolutionFailure(schema.to_owned()))?
-                .to_owned();
+    fn resolve_references(schemas: &Map<String, Value>, val: &mut Value) -> Result<(), InitError> {
+        if let Some(target) = Self::extract_ref(val) {
+            *val = schemas
+                .get(&target)
+                .ok_or(InitError::ResolutionFailure(format!(
+                    "{target} not found in the given schemas"
+                )))?
+                .clone();
         }
-        props
-            .values_mut()
-            .try_for_each(|obj| Self::resolve_nested(schemas, obj))
-    }
-
-    fn resolve_nested(schemas: &Map<String, Value>, val: &mut Value) -> Result<(), InitError> {
-        if let Some(Value::Object(inner_props)) = val.get_mut(Self::PROP) {
-            Self::resolve_references(schemas, inner_props)?;
-        } else if val.get(Self::ITM).is_some() {
-            // Rewrite - manually insert schema instead of calling resolve_references ?
-            if let Value::Object(false_props) = val {
-                Self::resolve_references(schemas, false_props)?;
+        match val {
+            Value::Object(ref mut map) => {
+                for v in map.values_mut() {
+                    Self::resolve_references(schemas, v)?;
+                }
+            }
+            Value::Array(ref mut arr) => {
+                for v in arr.iter_mut() {
+                    Self::resolve_references(schemas, v)?;
+                }
             }
-        } else if let Some(Value::Array(enum_arr)) = val.get_mut(Self::OOF) {
-            return enum_arr
-                .iter_mut()
-                .try_for_each(|obj| Self::resolve_nested(schemas, obj));
+            _ => (),
         }
         Ok(())
     }
 
-    /// Extract the fragment and pack it with the given field name
+    /// Extract the fragment and get the target field name
     #[inline]
     fn extract_ref(val: &Value) -> Option<String> {
         let refr = val.get(Self::REF)?;
diff --git a/tests/basic.rs b/tests/basic.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3d74ba3976b7ea67f148daa25f64d87f7af6553d
--- /dev/null
+++ b/tests/basic.rs
@@ -0,0 +1,196 @@
+#![allow(dead_code)]
+use serde::{Deserialize, Serialize};
+use std::sync::OnceLock;
+
+use utoipa::{OpenApi, ToSchema};
+
+#[derive(OpenApi)]
+#[openapi(components(schemas(
+    RegularSchema,
+    NestedSchema,
+    InnerSchema,
+    InnerInnerSchema,
+    Options,
+    SerdeSchema,
+    EnumType,
+)))]
+struct ApiDocs;
+
+#[derive(ToSchema)]
+struct RegularSchema {
+    #[schema(min_length = 1, max_length = 5)]
+    field: String,
+    #[schema(minimum = 5, maximum = 10)]
+    field2: i64,
+    field3: bool,
+    field4: Vec<String>,
+}
+
+#[derive(ToSchema)]
+struct NestedSchema {
+    #[schema(min_length = 1, max_length = 5)]
+    field: String,
+    nested: InnerSchema,
+}
+
+#[derive(ToSchema)]
+struct InnerSchema {
+    field: bool,
+    #[schema(minimum = 5, maximum = 10)]
+    field2: i32,
+    nested: InnerInnerSchema,
+}
+
+#[derive(ToSchema)]
+struct InnerInnerSchema {
+    #[schema(pattern = "^test$")]
+    field: String,
+    field2: Options,
+}
+
+#[derive(ToSchema)]
+enum Options {
+    One,
+    Two,
+    Three,
+}
+
+#[derive(Debug, Serialize, Deserialize, ToSchema)]
+pub struct SerdeSchema {
+    #[serde(flatten)]
+    flat: EnumType,
+    #[schema(min_length = 1)]
+    regular: String,
+}
+
+#[derive(Debug, Serialize, Deserialize, ToSchema)]
+#[serde(tag = "tag")]
+#[serde(rename_all = "lowercase")]
+pub enum EnumType {
+    First { field: String },
+    Second { field: String },
+    None,
+}
+
+fn get_schemas() -> &'static serde_json::Value {
+    static SCHEMAS: OnceLock<serde_json::Value> = OnceLock::new();
+    SCHEMAS.get_or_init(|| {
+        serde_json::to_value(
+            ApiDocs::openapi()
+                .components
+                .expect("no components found")
+                .schemas,
+        )
+        .unwrap()
+    })
+}
+
+#[test]
+fn init_validator_regular() {
+    let schemas = get_schemas();
+    schema_police::SchemaInspector::new_infer::<RegularSchema>(schemas, false).unwrap();
+}
+
+#[test]
+fn init_validator_nested() {
+    let schemas = get_schemas();
+    schema_police::SchemaInspector::new_infer::<NestedSchema>(schemas, true).unwrap();
+}
+
+#[test]
+fn init_validator_serde() {
+    let schemas = get_schemas();
+    schema_police::SchemaInspector::new_infer::<SerdeSchema>(schemas, true).unwrap();
+}
+
+#[test]
+fn validate_regular_schema_ok() {
+    let schemas = get_schemas();
+    let validator =
+        schema_police::SchemaInspector::new_infer::<RegularSchema>(schemas, false).unwrap();
+    let result = validator.inspect(&serde_json::json!({
+        "field": "field",
+        "field2": 8,
+        "field3": true,
+        "field4": [""],
+    }));
+    assert_eq!(result, Ok(()));
+}
+
+#[test]
+fn validate_regular_schema_err() {
+    let schemas = get_schemas();
+    let validator =
+        schema_police::SchemaInspector::new_infer::<RegularSchema>(schemas, false).unwrap();
+    let result = validator.inspect(&serde_json::json!({
+        "field": "eld",
+        "field2": 0,
+        "field3": true,
+        "field4": [""]
+    }));
+    assert!(result.is_err());
+}
+
+#[test]
+fn validate_nested_schema_ok() {
+    let schemas = get_schemas();
+    let validator =
+        schema_police::SchemaInspector::new_infer::<NestedSchema>(schemas, true).unwrap();
+    let result = validator.inspect(&serde_json::json!({
+        "field": "field",
+        "nested": {
+            "field": true,
+            "field2": 6,
+            "nested": {
+                "field": "test",
+                "field2": "One"
+            }
+        }
+    }));
+    assert_eq!(result, Ok(()));
+}
+
+#[test]
+fn validate_nested_schema_err() {
+    let schemas = get_schemas();
+    let validator =
+        schema_police::SchemaInspector::new_infer::<NestedSchema>(schemas, true).unwrap();
+    let result = validator.inspect(&serde_json::json!({
+        "field": "field",
+        "nested": {
+            "field": true,
+            "field2": 6,
+            "nested": {
+                "field": "",
+                "field2": "test"
+            }
+        }
+    }));
+    assert!(result.is_err())
+}
+
+#[test]
+fn validate_serde_schema_ok() {
+    let schemas = get_schemas();
+    let validator =
+        schema_police::SchemaInspector::new_infer::<SerdeSchema>(schemas, true).unwrap();
+    let result = validator.inspect(&serde_json::json!({
+        "regular": "field",
+        "tag": "first",
+        "field": ""
+    }));
+    assert_eq!(result, Ok(()));
+}
+
+#[test]
+fn validate_serde_schema_err() {
+    let schemas = get_schemas();
+    let validator =
+        schema_police::SchemaInspector::new_infer::<SerdeSchema>(schemas, true).unwrap();
+    let result = validator.inspect(&serde_json::json!({
+        "regular": "field",
+        "tag": "huh",
+        "field": ""
+    }));
+    assert!(result.is_err());
+}