#![allow(missing_docs)]
use crate::graph::Key;
use crate::versionedfiles::PyVersionedFiles;
use pyo3::prelude::*;
pub struct KnitVersionedFiles(Py<PyAny>);
impl KnitVersionedFiles {
pub fn new(py_obj: Py<PyAny>) -> Self {
Self(py_obj)
}
pub fn from_transport(
py: Python,
transport: &crate::transport::Transport,
file_mode: Option<u32>,
dir_mode: Option<u32>,
access_mode: Option<&str>,
) -> PyResult<Self> {
let knit_mod = py.import("breezy.bzr.knit")?;
let kvf_cls = knit_mod.getattr("KnitVersionedFiles")?;
let kwargs = pyo3::types::PyDict::new(py);
if let Some(mode) = file_mode {
kwargs.set_item("file_mode", mode)?;
}
if let Some(mode) = dir_mode {
kwargs.set_item("dir_mode", mode)?;
}
if let Some(mode) = access_mode {
kwargs.set_item("access_mode", mode)?;
}
let obj = kvf_cls.call((transport.as_pyobject().clone_ref(py),), Some(&kwargs))?;
Ok(KnitVersionedFiles(obj.unbind()))
}
}
impl Clone for KnitVersionedFiles {
fn clone(&self) -> Self {
Python::attach(|py| KnitVersionedFiles(self.0.clone_ref(py)))
}
}
impl PyVersionedFiles for KnitVersionedFiles {
fn to_object(&self, py: Python) -> Py<PyAny> {
self.0.clone_ref(py)
}
}
impl<'py> IntoPyObject<'py> for KnitVersionedFiles {
type Target = PyAny;
type Output = Bound<'py, Self::Target>;
type Error = PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
Ok(self.0.into_bound(py))
}
}
impl<'a, 'py> FromPyObject<'a, 'py> for KnitVersionedFiles {
type Error = PyErr;
fn extract(ob: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> {
Ok(KnitVersionedFiles(ob.to_owned().unbind()))
}
}
pub struct KnitPlainFactory {
pub key: Key,
pub parents: Vec<Key>,
pub sha1: Option<String>,
pub delta: Option<Vec<u8>>,
}
impl KnitPlainFactory {
pub fn new(key: Key, parents: Vec<Key>, sha1: Option<String>, delta: Option<Vec<u8>>) -> Self {
Self {
key,
parents,
sha1,
delta,
}
}
}
impl<'py> IntoPyObject<'py> for KnitPlainFactory {
type Target = PyAny;
type Output = Bound<'py, Self::Target>;
type Error = PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
let knit_mod = py.import("breezy.bzr.knit")?;
let factory_cls = knit_mod.getattr("KnitPlainFactory")?;
let factory = factory_cls.call0()?;
factory.setattr("key", self.key.into_pyobject(py)?)?;
let parent_tuples: Vec<_> = self
.parents
.into_iter()
.map(|p| p.into_pyobject(py))
.collect::<Result<Vec<_>, _>>()?;
let parents_py = pyo3::types::PyTuple::new(py, parent_tuples)?;
factory.setattr("parents", parents_py)?;
if let Some(sha1) = self.sha1 {
factory.setattr("sha1", pyo3::types::PyBytes::new(py, sha1.as_bytes()))?;
}
if let Some(delta) = self.delta {
factory.setattr("delta", pyo3::types::PyBytes::new(py, &delta))?;
}
Ok(factory)
}
}
pub struct KnitAnnotateFactory {
pub key: Key,
pub parents: Vec<Key>,
pub annotated_lines: Vec<(Key, String)>,
}
impl KnitAnnotateFactory {
pub fn new(key: Key, parents: Vec<Key>, annotated_lines: Vec<(Key, String)>) -> Self {
Self {
key,
parents,
annotated_lines,
}
}
}
impl<'py> IntoPyObject<'py> for KnitAnnotateFactory {
type Target = PyAny;
type Output = Bound<'py, Self::Target>;
type Error = PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
let knit_mod = py.import("breezy.bzr.knit")?;
let factory_cls = knit_mod.getattr("KnitAnnotateFactory")?;
let factory = factory_cls.call0()?;
factory.setattr("key", self.key.into_pyobject(py)?)?;
let parent_tuples: Vec<_> = self
.parents
.into_iter()
.map(|p| p.into_pyobject(py))
.collect::<Result<Vec<_>, _>>()?;
let parents_py = pyo3::types::PyTuple::new(py, parent_tuples)?;
factory.setattr("parents", parents_py)?;
let lines_list = pyo3::types::PyList::empty(py);
for (origin_key, line) in self.annotated_lines {
let tuple = pyo3::types::PyTuple::new(
py,
&[
origin_key.into_pyobject(py)?.into_any(),
line.into_pyobject(py)?.into_any(),
],
)?;
lines_list.append(tuple)?;
}
factory.setattr("annotated", lines_list)?;
Ok(factory)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_knit_plain_factory() {
crate::init();
crate::init_bzr();
pyo3::Python::attach(|py| {
let key = Key::from(vec!["file1".to_string()]);
let parents = vec![Key::from(vec!["parent1".to_string()])];
let factory = KnitPlainFactory::new(
key.clone(),
parents,
Some("abc123".to_string()),
Some(b"delta content".to_vec()),
);
let _py_obj = factory.into_pyobject(py).unwrap();
});
}
#[test]
fn test_knit_annotate_factory() {
crate::init();
crate::init_bzr();
pyo3::Python::attach(|py| {
let key = Key::from(vec!["file1".to_string()]);
let parents = vec![];
let annotated_lines = vec![
(
Key::from(vec!["origin1".to_string()]),
"line1\n".to_string(),
),
(
Key::from(vec!["origin1".to_string()]),
"line2\n".to_string(),
),
];
let factory = KnitAnnotateFactory::new(key, parents, annotated_lines);
let _py_obj = factory.into_pyobject(py).unwrap();
});
}
}