Skip to content

Commit

Permalink
add Cell::all, cleanup some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
emanueldima committed Mar 5, 2024
1 parent e45216d commit 41af9bd
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 88 deletions.
22 changes: 17 additions & 5 deletions issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
- explicit and implicit write support (policy, include readonly)
- fix tests, todo!() and TODO: in code

- change search: multiple path indices for one cell
- support type selector: `hial './src/tests/rust.rs^rust/:function_item'`
- support rust/ts write: `hial './src/tests/rust.rs^rust/:function_item[-1]#label = "modified_fn_name"'`
- support type selector: `hial './src/tests/rust.rs^rust/*[:function_item]'`
- support rust/ts write: `hial './src/tests/rust.rs^rust/*[:function_item].label = "modified_fn_name"'`
- set value on the command line
- separate api module, used by ffi and dependent crates
- new structure: /api, /api/impl, /interpretations/api, /interpretations/*, /search

-

- operations:
- assign to variables;
Expand All @@ -24,11 +25,12 @@
- new/set/replace/delete group (only sub or attr group)
- diff with assignment of results in variables

- ?change search: multiple path indices for one cell
- ?treesitter representations are too detailed, unsure what to do
- ?explore python implementation and usage
- ?search should return all matches embedded in a delegation cell, which has all results
as subs and delegates write operations to all the subs
- ?rename XCell, Cell, CellTrait to Nex?
- ?rename XCell, Cell, CellTrait to Nex/NexIn/NexInTrait
- later: python, git, database, ical, zip, markdown


Expand Down Expand Up @@ -98,3 +100,13 @@
'./**[.name=='config.yaml'][as composefile]^yaml/services/*/image[^string^http@status/code!=200]
tree 'result' -> [composefile] -> image
```

### Examples

1. Extract the general structure of a rust file. Get the struct/enum/type definitions (just the name and the type) and the function definitions (just the name and the signature). Get all implementations of traits and the functions inside them, as a tree.

```
hial 'item = ./src/tests/rust.rs^rust/**[:struct_item|:enum_item|:type_item|:function_item]; item/'
'
```
118 changes: 50 additions & 68 deletions src/base/extra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ use std::{
};

use crate::{
base::*,
enumerated_dynamic_type, guard_ok, guard_some,
interpretations::*,
pathlang::{search::Searcher, Path},
warning,
base::*, enumerated_dynamic_type, guard_ok, guard_some, interpretations::*,
pathlang::search::Searcher, warning,
};

const MAX_PATH_ITEMS: usize = 1000;
Expand Down Expand Up @@ -420,18 +417,44 @@ impl Cell {
}

pub fn to(&self, path: &str) -> Cell {
if let DynCell::Error(err) = &self.dyn_cell {
return self.clone();
}
let path = guard_ok!(crate::pathlang::Path::parse(path), err =>
return Cell {
dyn_cell: DynCell::from(err),
domain: Rc::clone(&self.domain),
}
);
PathSearch::new(self.clone(), path).first()
let mut searcher = Searcher::new(self.clone(), path);
match searcher.next() {
Some(Ok(c)) => c,
Some(Err(e)) => Cell {
dyn_cell: DynCell::from(e),
domain: Rc::clone(&self.domain),
},
None => {
let mut path = self.path().unwrap_or_default();
path += searcher.unmatched_path().as_str();
warning!("💥 path search failed: {}", path);
Cell {
dyn_cell: DynCell::from(noerr().with_path(path)),
domain: Rc::clone(&self.domain),
}
}
}
}

pub fn search<'a>(&self, path: &'a str) -> Res<PathSearch<'a>> {
pub fn search<'a>(&self, path: &'a str) -> Res<Searcher<'a>> {
if let DynCell::Error(err) = &self.dyn_cell {
return Err(err.clone());
}
let path = guard_ok!(crate::pathlang::Path::parse(path), err => {return Err(err)});
Ok(PathSearch::new(self.clone(), path))
Ok(Searcher::new(self.clone(), path))
}

pub fn all(&self, path: &str) -> Res<Vec<Cell>> {
self.search(path)?.collect()
}

pub fn head(&self) -> Res<(Cell, Relation)> {
Expand Down Expand Up @@ -621,15 +644,29 @@ impl Cell {
s
}

pub fn save(&self, target: Cell) -> Res<()> {
pub fn save(&self, target: &Cell) -> Res<()> {
if let DynCell::Error(err) = &self.dyn_cell {
return Err(err.clone());
}
if let DynCell::Error(err) = &target.dyn_cell {
return Err(err.clone());
}
let s = self.read().serial()?;
target.write().set_value(OwnValue::String(s))
Self::save_from_to(&self.dyn_cell, target)
}

pub fn save_domain(&self, target: &Cell) -> Res<()> {
if let DynCell::Error(err) = &target.dyn_cell {
return Err(err.clone());
}
let dyn_root = guard_some!(self.domain.dyn_root.get(), {
return fault("domain root not found while saving domain");
});
Self::save_from_to(dyn_root, target)
}

fn save_from_to(dyn_cell: &DynCell, target: &Cell) -> Res<()> {
let serial = dispatch_dyn_cell!(dyn_cell, |x| { x.read()?.serial()? });
target.write().set_value(OwnValue::String(serial))
}
}

Expand Down Expand Up @@ -679,25 +716,8 @@ impl Drop for Domain {
return;
});

let serial = dispatch_dyn_cell!(&dyn_root, |x| {
let r = guard_ok!(x.read(), e => {
warning!(
"💥 cannot read root while trying to auto-save domain: {:?}",
e
);
return;
});
guard_ok!(r.serial(), e => {
warning!("💥 cannot serialize root while trying to auto-save domain: {:?}", e);
return;
})
});

if let Err(e) = target.write().set_value(OwnValue::String(serial)) {
warning!(
"💥 cannot write to domain origin while trying to auto-save domain: {:?}",
e
);
if let Err(err) = Cell::save_from_to(dyn_root, target) {
warning!("💥 while trying to auto-save domain: {:?}", err);
}
}
}
Expand Down Expand Up @@ -954,41 +974,3 @@ impl CellIterator {
}
}
}

#[derive(Clone, Debug)]
pub struct PathSearch<'a> {
start: Cell,
// eval_iter: EvalIter<'a>,
searcher: Searcher<'a>,
}
impl<'a> PathSearch<'a> {
pub fn new(cell: Cell, path: Path<'a>) -> Self {
PathSearch {
start: cell.clone(),
searcher: Searcher::new(cell, path),
}
}

pub fn first(mut self) -> Cell {
match self.searcher.next() {
Some(Ok(c)) => c,
Some(Err(e)) => Cell {
dyn_cell: DynCell::from(e),
domain: Rc::clone(&self.start.domain),
},
None => {
let mut path = self.start.path().unwrap_or_default();
path += self.searcher.unmatched_path().as_str();
warning!("💥 path search failed: {}", path);
Cell {
dyn_cell: DynCell::from(noerr().with_path(path)),
domain: Rc::clone(&self.start.domain),
}
}
}
}

pub fn all(self) -> Res<Vec<Cell>> {
self.searcher.collect::<Res<Vec<_>>>()
}
}
7 changes: 5 additions & 2 deletions src/pathlang/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{

macro_rules! ifdebug {
( $body:expr ) => {
$body
// $body
};
}

Expand Down Expand Up @@ -101,7 +101,10 @@ impl<'s> Searcher<'s> {
"returning cell {:?}",
cell.as_ref().map(|x| x.debug_string())
));
return Some(cell);
match cell.and_then(|cell| cell.err()) {
Ok(cell) => return Some(Ok(cell)),
Err(e) => warning!("search error: {}", e),
}
}
}
None
Expand Down
4 changes: 2 additions & 2 deletions src/tests/ideals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ fn tree() -> Res<()> {
// and write back by doing a put request
let cell = Cell::from("./examples/write.json")
.policy(WritePolicy::WriteBackOnDrop)
.to("^path^fs^json/");
.to("^path^fs^json");
pprint(&cell, 0, 0);
assert!(cell.clone().err().is_ok());
// assert!(cell.write().set_value("weak as putty".into()).is_ok());

// let cell = Cell::from(".")
// .policy(WritePolicy::WriteBackOnDrop)
// .to("/examples/productiondump.json^file")
// .to("^path^fs/examples/productiondump.json")
// .to("^json/stacks/*/dockerCompose")
// .to("^docker.compose/services/scheduler/image")
// .to("^docker.imagetag/tag")
Expand Down
2 changes: 1 addition & 1 deletion src/tests/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ fn json_write_and_save() -> Res<()> {
assert_eq!(json.to(path1).read().value()?, newvalue);
assert_eq!(json.to(path2).read().value()?, Value::None);

json.save(json.origin())?;
json.save(&json.origin())?;

assert_eq!(
flattree.read().value()?.to_string(),
Expand Down
2 changes: 1 addition & 1 deletion src/tests/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn test_multihop_path() -> Res<()> {
let start = Cell::from("http://api.github.com");
let path = "^http^json/rate_limit_url^http^json/resources/core/limit";

let results = start.search(path)?.all()?;
let results = start.all(path)?;
assert_eq!(results.len(), 1);
let result = &results[0];

Expand Down
7 changes: 3 additions & 4 deletions src/tests/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ fn test_rust() -> Res<()> {
let folder = Cell::from(".").be("path").be("fs").err().unwrap();
let root = folder.to("/src/tests/rust.rs^rust");
assert_eq!(
root.search("/*[#type=='function_item']/name")?
.all()?
root.all("/*[#type=='function_item']/name")?
.into_iter()
.map(|c| c.debug_string())
.collect::<Vec<_>>(),
Expand Down Expand Up @@ -48,15 +47,15 @@ fn rust_write_and_save() -> Res<()> {
.set_value("modified_rust_fn".into())?;
assert_eq!(root.to("/[7]/[1]").read().value()?, "modified_rust_fn");

root.save(root.origin())?;
root.save(&root.origin())?;
assert_eq!(file.to("^rust/[7]/[1]").read().value()?, "modified_rust_fn",);

root.to("/[7]/[1]")
.write()
.set_value("editable_rust_fn".into())?;
assert_eq!(root.to("/[7]/[1]").read().value()?, "editable_rust_fn");

root.save(file.clone())?;
root.save(&file.clone())?;
assert_eq!(file.to("^rust/[7]/[1]").read().value()?, "editable_rust_fn",);

Ok(())
Expand Down
3 changes: 1 addition & 2 deletions src/tests/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,7 @@ fn search_double_kleene_with_filter() -> Res<()> {
}

pub fn str_eval(root: Cell, path: &str) -> Res<Vec<String>> {
root.search(path)?
.all()?
root.all(path)?
.into_iter()
.map(|cell| -> Res<String> {
// if let Ok(ref cell) = cres {
Expand Down
2 changes: 1 addition & 1 deletion src/tests/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn toml_write_and_save() -> Res<()> {
let v = toml.to("/number/x");
assert_eq!(v.read().value()?, Value::from(1.1415));

toml.save(toml.origin())?;
v.save_domain(&toml.origin())?;
let v = data.to("^toml/number/x");
assert_eq!(v.read().value()?, Value::from(1.1415));

Expand Down
2 changes: 1 addition & 1 deletion src/tests/xml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ fn xml_write_and_save() -> Res<()> {
xml.to("/doc/q/qq").write().set_value("444".into())?;
assert_eq!(xml.to("/doc/q/qq").read().value()?, "444");

xml.save(xml.origin())?;
xml.save(&xml.origin())?;
let v = text.to("^xml/doc/q/qq");
assert_eq!(v.read().value()?, "444");

Expand Down
2 changes: 1 addition & 1 deletion src/tests/yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fn yaml_write_and_save() -> Res<()> {
.set_value("putty".into())?;
assert_eq!(yaml.to("/hosts/[0]/labels/power").read().value()?, "putty");

yaml.save(yaml.origin())?;
yaml.save(&yaml.origin())?;
let v = text.to("^yaml/hosts/[0]/labels/power");
assert_eq!(v.read().value()?, "putty");

Expand Down

0 comments on commit 41af9bd

Please sign in to comment.