Skip to content

Commit

Permalink
Merge pull request #19 from calcit-lang/read-file-by-line
Browse files Browse the repository at this point in the history
new API read-file-by-line!
  • Loading branch information
NoEgAm authored Jul 5, 2023
2 parents 814807d + 01709b2 commit d9f06ed
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "calcit_std"
version = "0.0.20"
version = "0.1.1"
authors = ["jiyinyiyong <[email protected]>"]
edition = "2021"

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ calcit.std.fs/create-dir! path
calcit.std.fs/create-dir-all! path
calcit.std.fs/rename! from to
calcit.std.fs/read-file-by-line! a $ fn (line) (println line)
```

```cirru
Expand Down
59 changes: 58 additions & 1 deletion calcit.cirru

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions compact.cirru
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

{} (:package |calcit.std)
:configs $ {} (:init-fn |calcit.std.test/main!) (:reload-fn |calcit.std.test/reload!) (:version |0.1.0)
:configs $ {} (:init-fn |calcit.std.test/main!) (:reload-fn |calcit.std.test/reload!) (:version |0.1.1)
:modules $ []
:entries $ {}
:files $ {}
Expand Down Expand Up @@ -74,6 +74,9 @@
|read-file! $ quote
defn read-file! (name)
&call-dylib-edn (get-dylib-path "\"/dylibs/libcalcit_std") "\"read_file" name
|read-file-by-line! $ quote
defn read-file-by-line! (name cb)
&blocking-dylib-edn-fn (get-dylib-path "\"/dylibs/libcalcit_std") "\"read_file_by_line" name cb
|rename! $ quote
defn rename! (from to)
&call-dylib-edn (get-dylib-path "\"/dylibs/libcalcit_std") "\"rename_path" from to
Expand Down Expand Up @@ -232,6 +235,10 @@
println $ >
count $ read-file! "\"README.md"
, 1000
let
*c $ atom 0
read-file-by-line! "\"README.md" $ fn (line) (; println "\"readling line:" line) (swap! *c inc)
println "\"lines" @*c
println (path-exists? "\"README.md") (path-exists? "\"build.js")
println $ read-dir! "\"./"
println "\"dirs:" $ execute! ([] "\"ls")
Expand All @@ -245,7 +252,7 @@
:ns $ quote
ns calcit.std.test.fs $ :require
calcit.std.$meta :refer $ calcit-filename calcit-dirname
calcit.std.fs :refer $ read-file! append-file! write-file! path-exists? read-dir! create-dir! create-dir-all! rename! check-write-file! walk-dir! glob!
calcit.std.fs :refer $ read-file! append-file! write-file! path-exists? read-dir! create-dir! create-dir-all! rename! check-write-file! walk-dir! glob! read-file-by-line!
calcit.std.process :refer $ execute!
|calcit.std.test.json $ {}
:defs $ {}
Expand Down
47 changes: 46 additions & 1 deletion src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
use cirru_edn::Edn;
use glob::glob;
use std::fs;
use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
use std::sync::Arc;
use std::{fs, vec};
use walkdir::WalkDir;

#[no_mangle]
Expand All @@ -23,6 +26,48 @@ pub fn read_file(args: Vec<Edn>) -> Result<Edn, String> {
}
}

// The output is wrapped in a Result to allow matching on errors
// Returns an Iterator to the Reader of the lines of the file.
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where
P: AsRef<Path>,
{
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}

#[no_mangle]
pub fn read_file_by_line(
args: Vec<Edn>,
handler: Arc<dyn Fn(Vec<Edn>) -> Result<Edn, String> + Send + Sync + 'static>,
finish: Box<dyn FnOnce() + Send + Sync + 'static>,
) -> Result<Edn, String> {
if args.len() == 1 {
if let Edn::Str(name) = &args[0] {
match read_lines(&**name) {
Ok(lines) => {
// Consumes the iterator, returns an (Optional) String
for line in lines {
if let Ok(ip) = line {
match handler(vec![Edn::str(ip)]) {
Ok(_) => {}
Err(e) => return Err(format!("failed reading line: {}", e)),
}
}
}
finish();
Ok(Edn::Nil)
}
Err(e) => Err(format!("Failed to read file {name:?}: {e}")),
}
} else {
Err(format!("read-file-by-line expected 1 filename, got {:?}", &args[0]))
}
} else {
Err(format!("read-file-by-line expected 1 argument, got {args:?}"))
}
}

#[no_mangle]
pub fn write_file(args: Vec<Edn>) -> Result<Edn, String> {
if args.len() == 2 {
Expand Down

0 comments on commit d9f06ed

Please sign in to comment.