1use std::sync::Arc;
2
3use crate::core::config::Config;
4use crate::core::engine::Engine as DaggerEngine;
5use crate::core::graphql_client::DefaultGraphQLClient;
6
7use crate::errors::ConnectError;
8use crate::gen::Query;
9use crate::logging::StdLogger;
10use crate::querybuilder::query;
11
12pub type DaggerConn = Query;
13
14pub async fn connect<F, Fut>(dagger: F) -> Result<(), ConnectError>
15where
16 F: FnOnce(DaggerConn) -> Fut + 'static,
17 Fut: futures::Future<Output = eyre::Result<()>> + 'static,
18{
19 let cfg = Config::builder()
20 .logger(Arc::new(StdLogger::default()))
21 .build();
22
23 connect_opts(cfg, dagger).await
24}
25
26pub async fn connect_opts<F, Fut>(cfg: Config, dagger: F) -> Result<(), ConnectError>
27where
28 F: FnOnce(DaggerConn) -> Fut + 'static,
29 Fut: futures::Future<Output = eyre::Result<()>> + 'static,
30{
31 let (conn, proc) = DaggerEngine::new()
32 .start(&cfg)
33 .await
34 .map_err(ConnectError::FailedToConnect)?;
35
36 let proc = proc.map(Arc::new);
37
38 let client = Query {
39 proc: proc.clone(),
40 selection: query(),
41 graphql_client: Arc::new(DefaultGraphQLClient::new(&conn, &cfg)),
42 };
43
44 dagger(client).await.map_err(ConnectError::DaggerContext)?;
45
46 if let Some(proc) = &proc {
47 proc.shutdown()
48 .await
49 .map_err(ConnectError::FailedToShutdown)?;
50 }
51
52 Ok(())
53}
54
55#[cfg(test)]
58mod test {
59 use super::connect;
60
61 #[tokio::test]
62 async fn test_connect() -> eyre::Result<()> {
63 tracing_subscriber::fmt::init();
64
65 connect(|client| async move {
66 client
67 .container()
68 .from("alpine:latest")
69 .with_exec(vec!["echo", "1"])
70 .sync()
71 .await?;
72
73 Ok(())
74 })
75 .await?;
76
77 Ok(())
78 }
79}