<commit_before><?php

namespace Sokil\Rest\Transport;

class Structure implements \Serializable
{
    private $_data;
    
    public function __construct(array $data = null)
    {
        if($data) {
            $this->_data = $data;
        }
        
        $this->init();
    }
    
    public function init() {}
    
    public function setFromArray(array $data)
    {
        $this->_data = $data;
        return $this;
    }
    
    public function set($selector, $value)
    {
        // modify
        $arraySelector = explode('.', $selector);
        $chunksNum = count($arraySelector);
        
        // optimize one-level selector search
        if(1 == $chunksNum) {
            $this->_data[$selector] = $value;
            return $this;
        }
        
        // selector is nested
        $section = &$this->_data;

        for($i = 0; $i < $chunksNum - 1; $i++) {

            $field = $arraySelector[$i];

            if(!isset($section[$field])) {
                $section[$field] = array();
            }
            elseif(!is_array($section[$field])) {
                throw new Exception('Assigning array to scalar value');
            }

            $section = &$section[$field];
        }
        
        $section[$arraySelector[$chunksNum - 1]] = $value;
        
        return $this;
    }
    
    public function toArray()
    {
        return $this->_data;
    }
    
    public function __get($name)
    {
        return isset($this->_data[$name]) ? $this->_data[$name] : null;
    }
    
    public function get($selector)
    {
        if(false === strpos($selector, '.')) {
            return  isset($this->_data[$selector]) ? $this->_data[$selector] : null;
        }

        $value = $this->_data;
        foreach(explode('.', $selector) as $field)
        {
            if(!isset($value[$field])) {
                return null;
            }

            $value = $value[$field];
        }

        return $value;
    }
    
    public function getObject($selector, $className)
    {
        $data = $this->get($selector);
        if(!$data) {
            return null;
        }
        
        // get classname from callable
        if(is_callable($className)) {
            $className = $className($data);
        }
        
        // prepare structure
        $structure =  new $className();
        if(!($structure instanceof Structure)) {
            throw new Exception('Wring structure class specified');
        }
        
        return $structure->setFromArray($data);
    }
    
    /**
     * 
     * @param string $selector
     * @param string $className
     * @return \Sokil\Rest\StructureList
     * @throws \Exception
     */
    public function getObjectList($selector, $className)
    {        
        $list = new $className($this->get($selector));
        
        if(!($list instanceof StructureList)) {
            throw new \Exception('Must be iterator');
        }
        
        return $list;
    }
    
    public function serialize()
    {
        return json_encode($this->toArray());
    }
    
    public function unserialize($serialized)
    {
        $this->_data = json_decode($serialized, true);
        
        return $this;
    }
    
    public function __toString()
    {
        return $this->serialize();
    }
}
<commit_msg>allow convert structure to json<commit_after><?php

namespace Sokil\Rest\Transport;

class Structure implements \Serializable
{
    private $_data;
    
    public function __construct(array $data = null)
    {
        if($data) {
            $this->_data = $data;
        }
        
        $this->init();
    }
    
    public function init() {}
    
    public function setFromArray(array $data)
    {
        $this->_data = $data;
        return $this;
    }
    
    public function set($selector, $value)
    {
        // modify
        $arraySelector = explode('.', $selector);
        $chunksNum = count($arraySelector);
        
        // optimize one-level selector search
        if(1 == $chunksNum) {
            $this->_data[$selector] = $value;
            return $this;
        }
        
        // selector is nested
        $section = &$this->_data;

        for($i = 0; $i < $chunksNum - 1; $i++) {

            $field = $arraySelector[$i];

            if(!isset($section[$field])) {
                $section[$field] = array();
            }
            elseif(!is_array($section[$field])) {
                throw new Exception('Assigning array to scalar value');
            }

            $section = &$section[$field];
        }
        
        $section[$arraySelector[$chunksNum - 1]] = $value;
        
        return $this;
    }
    
    public function __get($name)
    {
        return isset($this->_data[$name]) ? $this->_data[$name] : null;
    }
    
    public function get($selector)
    {
        if(false === strpos($selector, '.')) {
            return  isset($this->_data[$selector]) ? $this->_data[$selector] : null;
        }

        $value = $this->_data;
        foreach(explode('.', $selector) as $field)
        {
            if(!isset($value[$field])) {
                return null;
            }

            $value = $value[$field];
        }

        return $value;
    }
    
    public function getObject($selector, $className)
    {
        $data = $this->get($selector);
        if(!$data) {
            return null;
        }
        
        // get classname from callable
        if(is_callable($className)) {
            $className = $className($data);
        }
        
        // prepare structure
        $structure =  new $className();
        if(!($structure instanceof Structure)) {
            throw new Exception('Wring structure class specified');
        }
        
        return $structure->setFromArray($data);
    }
    
    /**
     * 
     * @param string $selector
     * @param string $className
     * @return \Sokil\Rest\StructureList
     * @throws \Exception
     */
    public function getObjectList($selector, $className)
    {        
        $list = new $className($this->get($selector));
        
        if(!($list instanceof StructureList)) {
            throw new \Exception('Must be iterator');
        }
        
        return $list;
    }
    
    public function serialize()
    {
        return json_encode($this->toArray());
    }
    
    public function unserialize($serialized)
    {
        $this->_data = json_decode($serialized, true);
        
        return $this;
    }
    
    public function __toString()
    {
        return $this->serialize();
    }
    
    public function toJson() {
        return json_encode($this->toArray());
    }
     
    public function toArray()
    {
        return $this->_data;
    }
}

{'fraction_non_alphanumeric': 0.13546761523640136, 'fraction_numerical': 0.0011857121683711278, 'mean_word_length': 1.5824722541140452, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1674138', 'n_tokens_mistral': 1882, 'n_tokens_neox': 1847, 'n_words': 391}