diff --git a/schema/src/lib.rs b/schema/src/lib.rs
new file mode 100644
index 0000000..e246b8a
--- /dev/null
+++ b/schema/src/lib.rs
@@ -0,0 +1,353 @@
+use serde::{Serialize, Serializer};
+use std::collections::HashMap;
+use uuid::Uuid;
+
+/// Primitive OVSDB Atom types
+#[derive(Debug, Clone, PartialEq)]
+pub enum OvsdbAtom {
+    String(String),
+    Integer(i64),
+    Real(f64),
+    Boolean(bool),
+    Uuid(Uuid),
+    NamedUuid(String),
+}
+
+/// OVSDB Value types (atom, set, or map)
+#[derive(Debug, Clone, PartialEq)]
+pub enum OvsdbValue {
+    Atom(OvsdbAtom),
+    Set(Vec<OvsdbAtom>),
+    Map(Vec<(OvsdbAtom, OvsdbAtom)>),
+}
+
+/// Trait for converting between Rust types and OVSDB Values
+pub trait OvsdbSerializable: Sized {
+    fn to_ovsdb(&self) -> OvsdbValue;
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self>;
+}
+
+impl<T: OvsdbSerializable> OvsdbSerializable for Option<T> {
+    fn to_ovsdb(&self) -> OvsdbValue {
+        match self {
+            Some(val) => val.to_ovsdb(),
+            None => OvsdbValue::Set(vec![]), // Empty set for None
+        }
+    }
+
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self> {
+        T::from_ovsdb(value).map(Some)
+    }
+}
+
+impl OvsdbSerializable for String {
+    fn to_ovsdb(&self) -> OvsdbValue {
+        OvsdbValue::Atom(OvsdbAtom::String(self.clone()))
+    }
+
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self> {
+        match value {
+            OvsdbValue::Atom(OvsdbAtom::String(s)) => Some(s.clone()),
+            _ => None,
+        }
+    }
+}
+
+impl OvsdbSerializable for i64 {
+    fn to_ovsdb(&self) -> OvsdbValue {
+        OvsdbValue::Atom(OvsdbAtom::Integer(*self))
+    }
+
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self> {
+        match value {
+            OvsdbValue::Atom(OvsdbAtom::Integer(i)) => Some(*i),
+            _ => None,
+        }
+    }
+}
+
+impl OvsdbSerializable for f64 {
+    fn to_ovsdb(&self) -> OvsdbValue {
+        OvsdbValue::Atom(OvsdbAtom::Real(*self))
+    }
+
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self> {
+        match value {
+            OvsdbValue::Atom(OvsdbAtom::Real(r)) => Some(*r),
+            _ => None,
+        }
+    }
+}
+
+impl OvsdbSerializable for bool {
+    fn to_ovsdb(&self) -> OvsdbValue {
+        OvsdbValue::Atom(OvsdbAtom::Boolean(*self))
+    }
+
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self> {
+        match value {
+            OvsdbValue::Atom(OvsdbAtom::Boolean(b)) => Some(*b),
+            _ => None,
+        }
+    }
+}
+
+impl OvsdbSerializable for Uuid {
+    fn to_ovsdb(&self) -> OvsdbValue {
+        OvsdbValue::Atom(OvsdbAtom::Uuid(*self))
+    }
+
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self> {
+        match value {
+            OvsdbValue::Atom(OvsdbAtom::Uuid(uuid)) => Some(*uuid),
+            _ => None,
+        }
+    }
+}
+
+impl<T: OvsdbSerializable> OvsdbSerializable for Vec<T> {
+    fn to_ovsdb(&self) -> OvsdbValue {
+        if self.is_empty() {
+            return OvsdbValue::Set(vec![]);
+        }
+
+        // Try to convert each item to an OvsdbAtom
+        let mut atoms = Vec::with_capacity(self.len());
+        for item in self {
+            match item.to_ovsdb() {
+                OvsdbValue::Atom(atom) => atoms.push(atom),
+                _ => return OvsdbValue::Set(vec![]), // Invalid conversion, return empty set
+            }
+        }
+
+        OvsdbValue::Set(atoms)
+    }
+
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self> {
+        match value {
+            OvsdbValue::Set(atoms) => {
+                let mut result = Vec::with_capacity(atoms.len());
+                for atom in atoms {
+                    if let Some(item) = T::from_ovsdb(&OvsdbValue::Atom(atom.clone())) {
+                        result.push(item);
+                    } else {
+                        return None;
+                    }
+                }
+                Some(result)
+            }
+            // Handle single atom as a one-element set
+            OvsdbValue::Atom(atom) => {
+                T::from_ovsdb(&OvsdbValue::Atom(atom.clone())).map(|item| vec![item])
+            }
+            _ => None,
+        }
+    }
+}
+
+impl<K: OvsdbSerializable + ToString + Eq + std::hash::Hash, V: OvsdbSerializable> OvsdbSerializable
+    for HashMap<K, V>
+{
+    fn to_ovsdb(&self) -> OvsdbValue {
+        let mut pairs = Vec::with_capacity(self.len());
+
+        for (key, value) in self {
+            if let OvsdbValue::Atom(key_atom) = key.to_ovsdb() {
+                if let OvsdbValue::Atom(value_atom) = value.to_ovsdb() {
+                    pairs.push((key_atom, value_atom));
+                    continue;
+                }
+            }
+            return OvsdbValue::Map(vec![]);
+        }
+
+        OvsdbValue::Map(pairs)
+    }
+
+    fn from_ovsdb(value: &OvsdbValue) -> Option<Self> {
+        match value {
+            OvsdbValue::Map(map) => {
+                let mut result = HashMap::with_capacity(map.len());
+
+                for (key, val) in map {
+                    if let Some(key_converted) = K::from_ovsdb(&OvsdbValue::Atom(key.clone())) {
+                        if let Some(val_converted) = V::from_ovsdb(&OvsdbValue::Atom(val.clone())) {
+                            result.insert(key_converted, val_converted);
+                        } else {
+                            return None;
+                        }
+                    } else {
+                        return None;
+                    }
+                }
+
+                Some(result)
+            }
+            _ => None,
+        }
+    }
+}
+
+/// Custom serde serialization format for OvsdbValue
+/// Implements the specific JSON format required by OVSDB
+impl Serialize for OvsdbValue {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        match self {
+            OvsdbValue::Atom(atom) => atom.serialize(serializer),
+            OvsdbValue::Set(set) => {
+                if set.is_empty() {
+                    let empty: Vec<String> = vec![];
+                    empty.serialize(serializer)
+                } else if set.len() == 1 {
+                    set[0].serialize(serializer)
+                } else {
+                    let wrapper = ("set", set);
+                    wrapper.serialize(serializer)
+                }
+            }
+            OvsdbValue::Map(map) => {
+                let pairs: Vec<[&OvsdbAtom; 2]> = map.iter().map(|(k, v)| [k, v]).collect();
+                let wrapper = ("map", pairs);
+                wrapper.serialize(serializer)
+            }
+        }
+    }
+}
+
+impl Serialize for OvsdbAtom {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        match self {
+            OvsdbAtom::String(s) => s.serialize(serializer),
+            OvsdbAtom::Integer(i) => i.serialize(serializer),
+            OvsdbAtom::Real(r) => r.serialize(serializer),
+            OvsdbAtom::Boolean(b) => b.serialize(serializer),
+            OvsdbAtom::Uuid(uuid) => {
+                let wrapper = ("uuid", uuid.to_string());
+                wrapper.serialize(serializer)
+            }
+            OvsdbAtom::NamedUuid(name) => {
+                let wrapper = ("named-uuid", name);
+                wrapper.serialize(serializer)
+            }
+        }
+    }
+}
+
+/// Extension trait for OvsdbSerializable to handle JSON conversion
+pub trait OvsdbSerializableExt: OvsdbSerializable {
+    fn to_ovsdb_json(&self) -> Option<serde_json::Value> {
+        serde_json::to_value(self.to_ovsdb()).ok()
+    }
+
+    fn from_ovsdb_json(json: &serde_json::Value) -> Option<Self> {
+        // Convert JSON to OvsdbValue
+        let value = json_to_ovsdb_value(json)?;
+        Self::from_ovsdb(&value)
+    }
+}
+
+// Implement the extension trait for all types that implement OvsdbSerializable
+impl<T: OvsdbSerializable> OvsdbSerializableExt for T {}
+
+/// Helper function to extract a UUID from a JSON value
+pub fn extract_uuid(value: &serde_json::Value) -> Option<Uuid> {
+    if let serde_json::Value::Array(arr) = value {
+        if arr.len() == 2 && arr[0] == "uuid" {
+            if let serde_json::Value::String(uuid_str) = &arr[1] {
+                return Uuid::parse_str(uuid_str).ok();
+            }
+        }
+    }
+    None
+}
+
+/// Convert a JSON value to an OvsdbValue
+fn json_to_ovsdb_value(json: &serde_json::Value) -> Option<OvsdbValue> {
+    match json {
+        serde_json::Value::String(s) => Some(OvsdbValue::Atom(OvsdbAtom::String(s.clone()))),
+        serde_json::Value::Number(n) => {
+            if let Some(i) = n.as_i64() {
+                Some(OvsdbValue::Atom(OvsdbAtom::Integer(i)))
+            } else {
+                n.as_f64().map(|f| OvsdbValue::Atom(OvsdbAtom::Real(f)))
+            }
+        }
+        serde_json::Value::Bool(b) => Some(OvsdbValue::Atom(OvsdbAtom::Boolean(*b))),
+        serde_json::Value::Array(arr) => {
+            if arr.len() == 2 {
+                if let serde_json::Value::String(tag) = &arr[0] {
+                    match tag.as_str() {
+                        "uuid" => {
+                            if let serde_json::Value::String(uuid_str) = &arr[1] {
+                                if let Ok(uuid) = Uuid::parse_str(uuid_str) {
+                                    return Some(OvsdbValue::Atom(OvsdbAtom::Uuid(uuid)));
+                                }
+                            }
+                        }
+                        "named-uuid" => {
+                            if let serde_json::Value::String(name) = &arr[1] {
+                                return Some(OvsdbValue::Atom(OvsdbAtom::NamedUuid(name.clone())));
+                            }
+                        }
+                        "set" => {
+                            if let serde_json::Value::Array(elements) = &arr[1] {
+                                let mut atoms = Vec::with_capacity(elements.len());
+                                for elem in elements {
+                                    if let Some(OvsdbValue::Atom(atom)) = json_to_ovsdb_value(elem)
+                                    {
+                                        atoms.push(atom);
+                                    } else {
+                                        return None;
+                                    }
+                                }
+                                return Some(OvsdbValue::Set(atoms));
+                            }
+                        }
+                        "map" => {
+                            if let serde_json::Value::Array(pairs) = &arr[1] {
+                                let mut map_pairs = Vec::with_capacity(pairs.len());
+                                for pair in pairs {
+                                    if let serde_json::Value::Array(kv) = pair {
+                                        if kv.len() == 2 {
+                                            if let (
+                                                Some(OvsdbValue::Atom(key)),
+                                                Some(OvsdbValue::Atom(value)),
+                                            ) = (
+                                                json_to_ovsdb_value(&kv[0]),
+                                                json_to_ovsdb_value(&kv[1]),
+                                            ) {
+                                                map_pairs.push((key, value));
+                                                continue;
+                                            }
+                                        }
+                                    }
+                                    return None;
+                                }
+                                return Some(OvsdbValue::Map(map_pairs));
+                            }
+                        }
+                        _ => {}
+                    }
+                }
+            }
+
+            // Empty array means empty set
+            if arr.is_empty() {
+                return Some(OvsdbValue::Set(vec![]));
+            }
+
+            None
+        }
+        serde_json::Value::Null => {
+            // Null is represented as an empty set
+            Some(OvsdbValue::Set(vec![]))
+        }
+        _ => None,
+    }
+}
