pyadvreader 2.2.0

Split text file into text sequences, strings and (line) comments.
Documentation
use std::io::Error;
use std::path::PathBuf;
use std::str;

use advreader::AdvReturnValue;
use pyo3::conversion::IntoPy;
use pyo3::exceptions::{PyFileNotFoundError, PyValueError};
use pyo3::prelude::*;
use pyo3::types::{PyTuple, PyType};

pub mod return_value;

use return_value::{AdvReturnValueEnum, ReturnValueEnum};

#[pyclass]
#[derive(Debug)]
pub struct AdvReader {
    pub path: PathBuf,
    pub reader: advreader::AdvReaderIter,
    pub errors: Vec<Error>,
    pub return_type: bool,
}

#[pymethods]
impl AdvReader {
    #[new]
    fn __new__(
        path: PathBuf,
        buffer_size: Option<usize>,
        trim: Option<bool>,
        line_end: Option<u8>,
        skip_comments: Option<bool>,
        encode_comments: Option<bool>,
        encode_strings: Option<bool>,
        encoder: Option<String>,
        allow_invalid_utf8: Option<bool>,
        extended_word_separation: Option<bool>,
        double_double_quote_escape: Option<bool>,
        convert2numbers: Option<bool>,
        keep_base: Option<bool>,
        bool_false: Option<Vec<u8>>,
        bool_true: Option<Vec<u8>>,
        return_type: Option<bool>,
    ) -> PyResult<Self> {
        let reader = advreader::AdvReader::new(
            &path,
            buffer_size,
            trim,
            line_end,
            skip_comments,
            encode_comments,
            encode_strings,
            encoder,
            allow_invalid_utf8,
            extended_word_separation,
            double_double_quote_escape,
            convert2numbers,
            keep_base,
            bool_false,
            bool_true,
            None,
        );
        if let Err(e) = reader {
            return Err(PyFileNotFoundError::new_err(e.to_string()));
        }
        Ok(AdvReader {
            path,
            reader: reader.unwrap().into_iter(),
            errors: Vec::new(),
            return_type: return_type.unwrap_or(false),
        })
    }

    fn __enter__(slf: PyRef<Self>) -> PyResult<PyRef<Self>> {
        Ok(slf)
    }

    fn __exit__(
        &mut self,
        ty: Option<&PyType>,
        _value: Option<&PyAny>,
        _traceback: Option<&PyAny>,
        py: Python,
    ) -> PyResult<bool> {
        if let Err(e) = self.reader.stop() {
            return Err(PyValueError::new_err(e.to_string()));
        }
        match ty {
            Some(ty) => {
                if ty.eq(py.get_type::<PyValueError>()).unwrap() {
                    Ok(true)
                } else {
                    Ok(false)
                }
            }
            None => Ok(false),
        }
    }

    fn stop(&mut self) -> PyResult<bool> {
        if let Err(e) = self.reader.stop() {
            return Err(PyValueError::new_err(e.to_string()));
        }
        Ok(true)
    }

    fn next(&mut self, py: Python) -> PyResult<PyObject> {
        match self.reader.next() {
            Some(s) => match s {
                Ok(v) => {
                    if self.return_type {
                        match v {
                            AdvReturnValue::Bytes(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Bytes.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::String(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::String.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::Comment(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Comment.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::LineComment(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::LineComment.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::StringUtf8(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::StringUtf8.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::CommentUtf8(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::CommentUtf8.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::LineCommentUtf8(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[
                                        AdvReturnValueEnum::LineCommentUtf8.into_py(py),
                                        w.to_object(py),
                                    ],
                                )
                                .into())
                            }
                            AdvReturnValue::Bool(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Bool.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::Int(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Int.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::Float(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Float.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::Hex(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Hex.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::Oct(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Oct.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::Bin(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Bin.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                            AdvReturnValue::Block(w) => {
                                return Ok(PyTuple::new(
                                    py,
                                    &[AdvReturnValueEnum::Bin.into_py(py), w.to_object(py)],
                                )
                                .into())
                            }
                        }
                    } else {
                        match v {
                            AdvReturnValue::Bytes(w) => Ok(w.to_object(py)),
                            AdvReturnValue::String(w) => Ok(w.to_object(py)),
                            AdvReturnValue::Comment(w) => Ok(w.to_object(py)),
                            AdvReturnValue::LineComment(w) => Ok(w.to_object(py)),
                            AdvReturnValue::StringUtf8(w) => Ok(w.to_object(py)),
                            AdvReturnValue::CommentUtf8(w) => Ok(w.to_object(py)),
                            AdvReturnValue::LineCommentUtf8(w) => Ok(w.to_object(py)),
                            AdvReturnValue::Bool(w) => Ok(w.into_py(py)),
                            AdvReturnValue::Int(w) => Ok(w.into_py(py)),
                            AdvReturnValue::Float(w) => Ok(w.into_py(py)),
                            AdvReturnValue::Hex(w) => Ok(w.into_py(py)),
                            AdvReturnValue::Oct(w) => Ok(w.into_py(py)),
                            AdvReturnValue::Bin(w) => Ok(w.into_py(py)),
                            AdvReturnValue::Block(w) => Ok(w.into_py(py)),
                        }
                    }
                }
                Err(e) => Err(PyValueError::new_err(e.to_string())),
            },
            None => Ok(py.None()),
        }
    }

    #[getter]
    fn path(&self) -> PyResult<String> {
        Ok(self.path.clone().into_os_string().into_string().unwrap())
    }

    #[getter]
    fn line_nr(&self) -> PyResult<usize> {
        Ok(self.reader.line_nr())
    }

    #[getter]
    fn errors(&self) -> PyResult<Vec<String>> {
        let mut errors: Vec<String> = Vec::new();
        for error in self.errors.iter() {
            errors.push(format!("{}", error));
        }
        Ok(errors)
    }
}

#[pymodule]
fn pyadvreader(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add("__version__", env!("CARGO_PKG_VERSION"))?;
    m.add_class::<AdvReader>()?;
    m.add_class::<ReturnValueEnum>()?;
    Ok(())
}