hypershell_tokio_components/providers/
file.rs1use core::marker::PhantomData;
2use std::path::Path;
3
4use cgp::extra::handler::{Handler, HandlerComponent};
5use cgp::prelude::*;
6use hypershell_components::components::CanExtractCommandArg;
7use hypershell_components::dsl::{ReadFile, WriteFile};
8use tokio::fs::File;
9use tokio::io::AsyncRead;
10
11#[cgp_new_provider]
12impl<Context, PathArg> Handler<Context, ReadFile<PathArg>, ()> for HandleReadFile
13where
14 Context: CanExtractCommandArg<PathArg> + CanRaiseAsyncError<std::io::Error>,
15 PathArg: Send,
16 Context::CommandArg: Send + AsRef<Path>,
17{
18 type Output = File;
19
20 async fn handle(
21 context: &Context,
22 _tag: PhantomData<ReadFile<PathArg>>,
23 _input: (),
24 ) -> Result<File, Context::Error> {
25 let file_path = context.extract_command_arg(PhantomData);
26
27 let file = File::open(file_path.as_ref())
28 .await
29 .map_err(Context::raise_error)?;
30
31 Ok(file)
32 }
33}
34
35#[cgp_new_provider]
36impl<Context, PathArg, Input> Handler<Context, WriteFile<PathArg>, Input> for HandleWriteFile
37where
38 Context: CanExtractCommandArg<PathArg> + CanRaiseAsyncError<std::io::Error>,
39 PathArg: Send,
40 Context::CommandArg: Send + AsRef<Path>,
41 Input: Send + AsyncRead + Unpin,
42{
43 type Output = ();
44
45 async fn handle(
46 context: &Context,
47 _tag: PhantomData<WriteFile<PathArg>>,
48 mut input: Input,
49 ) -> Result<(), Context::Error> {
50 let file_path = context.extract_command_arg(PhantomData);
51
52 let mut file = File::create(file_path.as_ref())
53 .await
54 .map_err(Context::raise_error)?;
55
56 tokio::io::copy(&mut input, &mut file)
57 .await
58 .map_err(Context::raise_error)?;
59
60 Ok(())
61 }
62}