···3838 These functions provide simple file I/O with the filesystem from {!Eio.Stdenv.fs}. *)
39394040(** Read and parse GPX file.
4141- @param fs Filesystem capability
4241 @param path File path to read
4342 @param ?validate Optional validation flag (default: false)
4443 @return GPX document
4544 @raises Gpx.Gpx_error on read or parse failure *)
4646-val read : ?validate:bool -> fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> Gpx.t
4545+val read : ?validate:bool -> _ Eio.Path.t -> Gpx.t
47464847(** Write GPX to file.
4949- @param fs Filesystem capability
5048 @param path File path to write
5149 @param gpx GPX document to write
5250 @param ?validate Optional validation flag (default: false)
5351 @raises Gpx.Gpx_error on write failure *)
5454-val write : ?validate:bool -> fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> Gpx.t -> unit
5252+val write : ?validate:bool -> _ Eio.Path.t -> Gpx.t -> unit
55535654(** Write GPX to file with automatic backup.
5757- @param fs Filesystem capability
5855 @param path File path to write
5956 @param gpx GPX document to write
6057 @param ?validate Optional validation flag (default: false)
6161- @return Backup file path (empty if no backup created)
5858+ @return Backup file path ([None] if no backup created)
6259 @raises Gpx.Gpx_error on failure *)
6363-val write_with_backup : ?validate:bool -> fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> Gpx.t -> string
6060+val write_with_backup : ?validate:bool -> 'a Eio.Path.t -> Gpx.t -> 'a Eio.Path.t option
64616562(** {2 Stream Operations}
6663···7168 @param ?validate Optional validation flag (default: false)
7269 @return GPX document
7370 @raises Gpx.Gpx_error on read or parse failure *)
7474-val from_source : ?validate:bool -> [> Eio.Flow.source_ty ] Eio.Resource.t -> Gpx.t
7171+val from_source : ?validate:bool -> _ Eio.Flow.source -> Gpx.t
75727673(** Write GPX to Eio sink.
7774 @param sink Output flow
7875 @param gpx GPX document
7976 @param ?validate Optional validation flag (default: false)
8077 @raises Gpx.Gpx_error on write failure *)
8181-val to_sink : ?validate:bool -> [> Eio.Flow.sink_ty ] Eio.Resource.t -> Gpx.t -> unit
7878+val to_sink : ?validate:bool -> _ Eio.Flow.sink -> Gpx.t -> unit
82798380(** Print GPX statistics to sink.
8481 @param sink Output sink
8582 @param gpx GPX document *)
8686-val print_stats : [> Eio.Flow.sink_ty ] Eio.Resource.t -> Gpx.t -> unit
8383+val print_stats : _ Eio.Flow.sink -> Gpx.t -> unit
+27-29
lib/gpx_eio/gpx_io.ml
···11(** GPX Eio I/O operations *)
2233(** Read GPX from file path *)
44-let read_file ?(validate=false) ~fs path =
55- let content = Eio.Path.load Eio.Path.(fs / path) in
44+let read_file ?(validate=false) path =
55+ let content = Eio.Path.load path in
66 match Gpx.parse_string ~validate content with
77 | Ok gpx -> gpx
88 | Error err -> raise (Gpx.Gpx_error err)
991010(** Write GPX to file path *)
1111-let write_file ?(validate=false) ~fs path gpx =
1111+let write_file ?(validate=false) path gpx =
1212 match Gpx.write_string ~validate gpx with
1313 | Ok xml_string ->
1414- Eio.Path.save ~create:(`Or_truncate 0o644) Eio.Path.(fs / path) xml_string
1414+ Eio.Path.save ~create:(`Or_truncate 0o644) path xml_string
1515 | Error err -> raise (Gpx.Gpx_error err)
16161717(** Read GPX from Eio source *)
···2929 | Error err -> raise (Gpx.Gpx_error err)
30303131(** Check if file exists *)
3232-let file_exists ~fs path =
3333- try
3434- let _stat = Eio.Path.stat ~follow:true Eio.Path.(fs / path) in
3535- true
3636- with
3737- | _ -> false
3232+let file_exists = Eio.Path.is_file
38333934(** Get file size *)
4040-let file_size ~fs path =
3535+let file_size path =
4136 try
4242- let stat = Eio.Path.stat ~follow:true Eio.Path.(fs / path) in
3737+ let stat = Eio.Path.stat ~follow:true path in
4338 Optint.Int63.to_int stat.size
4439 with
4540 | exn -> raise (Gpx.Gpx_error (Gpx.Error.io_error (Printexc.to_string exn)))
46414742(** Create backup of existing file *)
4848-let create_backup ~fs path =
4949- if file_exists ~fs path then
5050- let backup_path = path ^ ".backup" in
5151- let content = Eio.Path.load Eio.Path.(fs / path) in
5252- Eio.Path.save ~create:(`Or_truncate 0o644) Eio.Path.(fs / backup_path) content;
5353- backup_path
4343+let create_backup ((fs, inner_path) as path) =
4444+ if file_exists path then
4545+ let backup_path = inner_path ^ ".backup" in
4646+ let content = Eio.Path.load path in
4747+ Eio.Path.save ~create:(`Or_truncate 0o644) (fs, backup_path) content;
4848+ Some (fs, backup_path)
5449 else
5555- ""
5050+ None
56515752(** Write GPX to file with automatic backup *)
5858-let write_file_with_backup ?(validate=false) ~fs path gpx =
5959- let backup_path = create_backup ~fs path in
5353+let write_file_with_backup ?(validate=false) path gpx =
5454+ let backup_path = create_backup path in
6055 try
6161- write_file ~validate ~fs path gpx;
5656+ write_file ~validate path gpx;
6257 backup_path
6358 with
6459 | Gpx.Gpx_error _ as err ->
6560 (* Try to restore backup if write failed *)
6666- if backup_path <> "" && file_exists ~fs backup_path then (
6767- try
6868- let backup_content = Eio.Path.load Eio.Path.(fs / backup_path) in
6969- Eio.Path.save ~create:(`Or_truncate 0o644) Eio.Path.(fs / path) backup_content
7070- with _ -> () (* Ignore restore errors *)
7171- );
7272- raise err
6161+ match backup_path with
6262+ | Some backup_path ->
6363+ if file_exists backup_path then (
6464+ try
6565+ let backup_content = Eio.Path.load backup_path in
6666+ Eio.Path.save ~create:(`Or_truncate 0o644) path backup_content
6767+ with _ -> () (* Ignore restore errors *)
6868+ );
6969+ raise err
7070+ | _ -> raise err
+7-13
lib/gpx_eio/gpx_io.mli
···88(** {1 File Operations} *)
991010(** Read GPX from file path.
1111- @param fs Filesystem capability
1211 @param path File path to read
1312 @param ?validate Optional validation flag (default: false)
1413 @return GPX document or error *)
1515-val read_file : ?validate:bool -> fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> Gpx.t
1414+val read_file : ?validate:bool -> _ Eio.Path.t -> Gpx.t
16151716(** Write GPX to file path.
1818- @param fs Filesystem capability
1917 @param path File path to write
2018 @param gpx GPX document to write
2119 @param ?validate Optional validation flag (default: false)
2220 @raises Gpx.Gpx_error on write failure *)
2323-val write_file : ?validate:bool -> fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> Gpx.t -> unit
2121+val write_file : ?validate:bool -> _ Eio.Path.t -> Gpx.t -> unit
24222523(** {1 Stream Operations}
2624···4139(** {1 Utility Functions} *)
42404341(** Check if file exists.
4444- @param fs Filesystem capability
4542 @param path File path to check
4643 @return [true] if file exists and is readable *)
4747-val file_exists : fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> bool
4444+val file_exists : _ Eio.Path.t -> bool
48454946(** Get file size.
5050- @param fs Filesystem capability
5147 @param path File path
5248 @return File size in bytes *)
5353-val file_size : fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> int
4949+val file_size : _ Eio.Path.t -> int
54505551(** Create backup of existing file.
5656- @param fs Filesystem capability
5752 @param path Original file path
5853 @return Backup file path *)
5959-val create_backup : fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> string
5454+val create_backup : 'a Eio.Path.t -> 'a Eio.Path.t option
60556156(** Write GPX to file with automatic backup.
6257 Creates a backup of existing file before writing new content.
6363- @param fs Filesystem capability
6458 @param path File path to write
6559 @param gpx GPX document to write
6660 @param ?validate Optional validation flag (default: false)
6767- @return Backup file path (empty string if no backup needed) *)
6868-val write_file_with_backup : ?validate:bool -> fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> string -> Gpx.t -> string
6161+ @return Backup file path ([None] if no backup needed) *)
6262+val write_file_with_backup : ?validate:bool -> 'a Eio.Path.t -> Gpx.t -> 'a Eio.Path.t option
+7-5
test/test_corpus_unix_eio.ml
···2233open Alcotest
4455+let ( / ) = Eio.Path. ( / )
66+57let test_data_dir = "test/data"
6879let test_files = [
···4446 let fs = Eio.Stdenv.fs env in
4547 let path = Filename.concat test_data_dir filename in
4648 try
4747- let gpx = Gpx_eio.read ~fs path in
4949+ let gpx = Gpx_eio.read (fs / path) in
4850 let validation = Gpx.validate_gpx gpx in
4951 check bool "GPX is valid" true validation.is_valid;
5052 check bool "Has some content" true (
···6870 try
6971 Eio_main.run @@ fun env ->
7072 let fs = Eio.Stdenv.fs env in
7171- Ok (Gpx_eio.read ~fs path)
7373+ Ok (Gpx_eio.read (fs / path))
7274 with
7375 | Gpx.Gpx_error err -> Error err
7476 in
···120122 let fs = Eio.Stdenv.fs env in
121123 let path = Filename.concat test_data_dir filename in
122124 try
123123- let gpx_original = Gpx_eio.read ~fs path in
125125+ let gpx_original = Gpx_eio.read (fs / path) in
124126 (* Write to temporary string via GPX core *)
125127 match Gpx.write_string gpx_original with
126128 | Ok xml_string ->
···171173 (try
172174 Eio_main.run @@ fun env ->
173175 let fs = Eio.Stdenv.fs env in
174174- let _ = Gpx_eio.read ~fs path in
176176+ let _ = Gpx_eio.read (fs / path) in
175177 failf "Eio should have failed to parse invalid.gpx"
176178 with
177179 | Gpx.Gpx_error _ ->
···190192 let start_eio = Sys.time () in
191193 let _ = Eio_main.run @@ fun env ->
192194 let fs = Eio.Stdenv.fs env in
193193- try Some (Gpx_eio.read ~fs path)
195195+ try Some (Gpx_eio.read (fs / path))
194196 with Gpx.Gpx_error _ -> None
195197 in
196198 let eio_time = Sys.time () -. start_eio in