You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: modifier.rs
    path of file: ./repos/tikv/components/tidb_query_datatype/src/codec/mysql/json
    
    the code of the file until where you have to start completion: // Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.

use std::ptr;

use codec::number::NumberCodec;

use super::{
    super::Result,
    constants::*,
    json_extract::extract_json,
    path_expr::{PathExpression, PathLeg},
    Json, JsonRef, JsonType,
};
use crate::codec::mysql::json::path_expr::{ArraySelection, KeySelection};

/// A helper struct that derives a new JSON by combining and manipulating
/// the encoded bytes directly. Only used by `json_replace`, `json_set`,
/// `json_insert` and `json_remove`
///
/// See `binaryModifier` in TiDB `json/binary_function.go`
pub struct BinaryModifier<'a> {
    // The target Json to be modified
    old: JsonRef<'a>,
    // The ptr point to the memory location of `old.value` that `new_value` should be appended
    to_be_modified_ptr: *const u8,
    // The new encoded value
    // TODO(fullstop000): Can we just use Json instead ?
    new_value: Option<Json>,
}

impl<'a> BinaryModifier<'a> {
    /// Creates a new `BinaryModifier` from a `JsonRef`
    pub fn new(old: JsonRef<'a>) -> BinaryModifier<'_> {
        Self {
            // The initial offset is 0 by `as_ref()` call
            old,
            // Mark invalid
            to_be_modified_ptr: ptr::null(),
            new_value: None,
        }
    }

    /// Replaces the existing value JSON and adds nonexisting value
    /// specified by the expression path with `new`
    pub fn set(mut self, path: &PathExpression, new: Json) -> Result<Json> {
        let result = extract_json(self.old, path.legs.as_slice())?;
        if !result.is_empty() {
            self.to_be_modified_ptr = result[0].as_ptr();
            self.new_value = Some(new);
        } else {
            self.do_insert(&path.legs, new)?;
        }
        self.rebuild()
    }

    /// Replaces the existing value JSON specified by the expression path with
    /// `new`
    pub fn replace(mut self, path: &PathExpression, new: Json)
    
    fn rebuild_to(&mut self, buf: &mut Vec<u8>) -> Result<JsonType> {
        if self.to_be_modified_ptr == self.old.as_ptr() {
            // Replace the old directly
            self.to_be_modified_ptr = ptr::null();
            buf.extend_from_slice(&self.new_value.as_ref().unwrap().value);
            return Ok(self.new_value.as_ref().unwrap().as_ref().get_type());
        } else if self.to_be_modified_ptr.is_null() {
            // No modification, use the old one
            buf.extend_from_slice(self.old.value);
            return Ok(self.old.get_type());
        }
        let tp = self.old.get_type();
        match tp {
            JsonType::Object | JsonType::Array => {
                let doc_off = buf.len();
                let elem_count = self.old.get_elem_count();
                let current = self.old;
                let val_entry_start = match current.get_type() {
                    JsonType::Array => {
                        let copy_size = HEADER_LEN + elem_count * VALUE_ENTRY_LEN;
                        buf.extend_from_slice(&current.value[..copy_size]);
                        HEADER_LEN
                    }
                    JsonType::Object => {
                        let copy_size = HEADER_LEN + elem_count * (KEY_ENTRY_LEN + VALUE_ENTRY_LEN);
                        // Append kv entries
                        buf.extend_from_slice(&current.value[..copy_size]);
                        // Append keys
                        if elem_count > 0 {
                            let first_key_offset =
                                NumberCodec::decode_u32_le(&current.value[HEADER_LEN..]) as usize;
                            let last_key_offset = NumberCodec::decode_u32_le(
                                &current.value[HEADER_LEN + (elem_count - 1) * KEY_ENTRY_LEN..],
                            ) as usize;
                            let last_key_len = NumberCodec::decode_u16_le(
                                &current.value
                                    [HEADER_LEN + (elem_count - 1) * KEY_ENTRY_LEN + U32_LEN..],
                            ) as usize;
                            buf.extend_from_slice(
                                &current.value[first_key_offset..last_key_offset + last_key_len],
                            );
                        }
                        HEADER_LEN + elem_count * KEY_ENTRY_LEN
                    }
                    // This must be impossible
                    _ => return Err(box_err!("Unexpected source json type")),
                };
                // Resolve values
                for i in 0..elem_count {
                    let val_entry_offset = val_entry_start + i * VALUE_ENTRY_LEN;
                    self.old = current.val_entry_get(val_entry_offset)?;
                    let val_offset = buf.len() - doc_off;
                    // loop until finding the target ptr to be modified
                    let new_tp = self.rebuild_to(buf)?;
                    buf[doc_off + val_entry_offset] = new_tp as u8;
                    match new_tp {
                        JsonType::Literal => {
                            let last_idx = buf.len() - 1;
                            let val = u32::from(buf[last_idx]);
                            NumberCodec::encode_u32_le(
                                &mut buf[doc_off + val_entry_offset + TYPE_LEN..],
                                val,
                            );
                            // TODO: is this necessary?
                            buf.resize(last_idx, 0);
                        }
                        _ => {
                            NumberCodec::encode_u32_le(
                                &mut buf[doc_off + val_entry_offset + TYPE_LEN..],
                                val_offset as u32,
                            );
                        }
                    }
                }
                let data_len = buf.len() - doc_off;
                NumberCodec::encode_u32_le(
                    &mut buf[doc_off + ELEMENT_COUNT_LEN..],
                    data_len as u32,
                );
            }
            _ => {
                buf.extend_from_slice(self.old.value);
            }
        }
        Ok(tp)
    }