use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use pyo3::types::PyBytes;
use synta::{
BmpString, FromDer, GeneralString, IA5String, NumericString, PrintableString, TeletexString,
ToDer, UniversalString, Utf8String, VisibleString,
};
use crate::error::SyntaErr;
#[pyclass(name = "Utf8String")]
#[derive(Debug, Clone)]
pub struct PyUtf8String {
pub(crate) inner: Utf8String,
}
#[pymethods]
impl PyUtf8String {
#[new]
fn new(value: &str) -> Self {
Self {
inner: Utf8String::new(value.to_string()),
}
}
fn as_str(&self) -> &str {
self.inner.as_str()
}
fn __str__(&self) -> &str {
self.inner.as_str()
}
fn __repr__(&self) -> String {
format!("Utf8String('{}')", self.inner.as_str())
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn __len__(&self) -> usize {
self.inner.as_str().chars().count()
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = Utf8String::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}
#[pyclass(name = "PrintableString")]
#[derive(Debug, Clone)]
pub struct PyPrintableString {
pub(crate) inner: PrintableString,
}
#[pymethods]
impl PyPrintableString {
#[new]
fn new(value: &str) -> PyResult<Self> {
let inner = PrintableString::new(value.to_string())
.map_err(|e| PyValueError::new_err(format!("Invalid PrintableString: {:?}", e)))?;
Ok(Self { inner })
}
fn as_str(&self) -> &str {
self.inner.as_str()
}
fn __str__(&self) -> &str {
self.inner.as_str()
}
fn __repr__(&self) -> String {
format!("PrintableString('{}')", self.inner.as_str())
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn __len__(&self) -> usize {
self.inner.as_str().chars().count()
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = PrintableString::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}
#[pyclass(name = "IA5String")]
#[derive(Debug, Clone)]
pub struct PyIA5String {
pub(crate) inner: IA5String,
}
#[pymethods]
impl PyIA5String {
#[new]
fn new(value: &str) -> PyResult<Self> {
let inner = IA5String::new(value.to_string())
.map_err(|e| PyValueError::new_err(format!("Invalid IA5String: {:?}", e)))?;
Ok(Self { inner })
}
fn as_str(&self) -> &str {
self.inner.as_str()
}
fn __str__(&self) -> &str {
self.inner.as_str()
}
fn __repr__(&self) -> String {
format!("IA5String('{}')", self.inner.as_str())
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn __len__(&self) -> usize {
self.inner.as_str().chars().count()
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = IA5String::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}
#[pyclass(name = "NumericString")]
#[derive(Debug, Clone)]
pub struct PyNumericString {
pub(crate) inner: NumericString,
}
#[pymethods]
impl PyNumericString {
#[new]
fn new(value: &str) -> PyResult<Self> {
let inner = NumericString::new(value.to_string())
.map_err(|e| PyValueError::new_err(format!("Invalid NumericString: {:?}", e)))?;
Ok(Self { inner })
}
fn as_str(&self) -> &str {
self.inner.as_str()
}
fn __str__(&self) -> &str {
self.inner.as_str()
}
fn __repr__(&self) -> String {
format!("NumericString('{}')", self.inner.as_str())
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn __len__(&self) -> usize {
self.inner.as_str().chars().count()
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = NumericString::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}
#[pyclass(name = "TeletexString")]
#[derive(Debug, Clone)]
pub struct PyTeletexString {
pub(crate) inner: TeletexString,
}
#[pymethods]
impl PyTeletexString {
#[new]
fn new(data: Vec<u8>) -> Self {
Self {
inner: TeletexString::new(data),
}
}
#[staticmethod]
fn from_latin1(value: &str) -> PyResult<Self> {
TeletexString::from_latin1(value)
.map(|inner| Self { inner })
.map_err(|e| PyValueError::new_err(format!("{:?}", e)))
}
#[staticmethod]
fn from_str(value: &str) -> PyResult<Self> {
TeletexString::from_latin1(value)
.map(|inner| Self { inner })
.map_err(|e| PyValueError::new_err(format!("{:?}", e)))
}
fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, self.inner.as_bytes())
}
fn as_str(&self) -> String {
self.inner.as_latin1_string()
}
fn __str__(&self) -> String {
self.inner.as_latin1_string()
}
fn __repr__(&self) -> String {
format!("TeletexString(<{} bytes>)", self.inner.as_bytes().len())
}
fn __len__(&self) -> usize {
self.inner.as_bytes().len()
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = TeletexString::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}
#[pyclass(name = "VisibleString")]
#[derive(Debug, Clone)]
pub struct PyVisibleString {
pub(crate) inner: VisibleString,
}
#[pymethods]
impl PyVisibleString {
#[new]
fn new(value: &str) -> PyResult<Self> {
let inner = VisibleString::new(value.to_string())
.map_err(|e| PyValueError::new_err(format!("Invalid VisibleString: {:?}", e)))?;
Ok(Self { inner })
}
fn as_str(&self) -> &str {
self.inner.as_str()
}
fn __str__(&self) -> &str {
self.inner.as_str()
}
fn __repr__(&self) -> String {
format!("VisibleString('{}')", self.inner.as_str())
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn __len__(&self) -> usize {
self.inner.as_str().len()
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = VisibleString::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}
#[pyclass(name = "GeneralString")]
#[derive(Debug, Clone)]
pub struct PyGeneralString {
pub(crate) inner: GeneralString,
}
#[pymethods]
impl PyGeneralString {
#[new]
fn new(data: Vec<u8>) -> Self {
Self {
inner: GeneralString::new(data),
}
}
#[staticmethod]
fn from_ascii(value: &str) -> PyResult<Self> {
GeneralString::from_ascii(value)
.map(|inner| Self { inner })
.map_err(|e| PyValueError::new_err(format!("{:?}", e)))
}
#[staticmethod]
fn from_str(value: &str) -> PyResult<Self> {
GeneralString::from_ascii(value)
.map(|inner| Self { inner })
.map_err(|e| PyValueError::new_err(format!("{:?}", e)))
}
fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, self.inner.as_bytes())
}
fn as_str(&self) -> String {
self.inner.as_latin1_string()
}
fn __str__(&self) -> String {
self.inner.as_latin1_string()
}
fn __repr__(&self) -> String {
format!("GeneralString(<{} bytes>)", self.inner.as_bytes().len())
}
fn __len__(&self) -> usize {
self.inner.as_bytes().len()
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = GeneralString::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}
#[pyclass(name = "UniversalString")]
#[derive(Debug, Clone)]
pub struct PyUniversalString {
pub(crate) inner: UniversalString,
}
#[pymethods]
impl PyUniversalString {
#[new]
fn new(value: &str) -> Self {
Self {
inner: UniversalString::new(value.to_string()),
}
}
#[staticmethod]
fn from_bytes(data: &[u8]) -> PyResult<Self> {
let inner = UniversalString::from_ucs4_be(data)
.map_err(|e| PyValueError::new_err(format!("Invalid UniversalString: {:?}", e)))?;
Ok(Self { inner })
}
fn as_str(&self) -> &str {
self.inner.as_str()
}
fn __str__(&self) -> &str {
self.inner.as_str()
}
fn __repr__(&self) -> String {
format!("UniversalString('{}')", self.inner.as_str())
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn __len__(&self) -> usize {
self.inner.as_str().chars().count()
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = UniversalString::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}
#[pyclass(name = "BmpString")]
#[derive(Debug, Clone)]
pub struct PyBmpString {
pub(crate) inner: BmpString,
}
#[pymethods]
impl PyBmpString {
#[new]
fn new(value: &str) -> PyResult<Self> {
let inner = BmpString::new(value.to_string())
.map_err(|e| PyValueError::new_err(format!("Invalid BMPString: {:?}", e)))?;
Ok(Self { inner })
}
#[staticmethod]
fn from_bytes(data: &[u8]) -> PyResult<Self> {
let inner = BmpString::from_ucs2_be(data)
.map_err(|e| PyValueError::new_err(format!("Invalid BMPString: {:?}", e)))?;
Ok(Self { inner })
}
fn as_str(&self) -> &str {
self.inner.as_str()
}
fn __str__(&self) -> &str {
self.inner.as_str()
}
fn __repr__(&self) -> String {
format!("BmpString('{}')", self.inner.as_str())
}
fn __eq__(&self, other: &Self) -> bool {
self.inner == other.inner
}
fn __len__(&self) -> usize {
self.inner.as_str().chars().count()
}
fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
}
#[staticmethod]
fn from_der(data: &[u8]) -> PyResult<Self> {
let inner = BmpString::from_der(data).map_err(SyntaErr)?;
Ok(Self { inner })
}
}