Skip to main content

libgrite_cli/
actor.rs

1use libgrite_core::{
2    config::{
3        actor_dir, list_actors, load_actor_config, load_repo_config, save_actor_config,
4        save_repo_config,
5    },
6    signing::SigningKeyPair,
7    types::actor::ActorConfig,
8    types::ids::{generate_actor_id, id_to_hex},
9    GriteError,
10};
11
12use crate::context::GriteContext;
13use crate::types::*;
14
15/// Create a new actor.
16pub fn actor_init(opts: &ActorInitOptions) -> Result<ActorInitResult, GriteError> {
17    let git_dir = GriteContext::find_git_dir()?;
18
19    let actor_id = generate_actor_id();
20    let actor_id_hex = id_to_hex(&actor_id);
21    let data_dir = actor_dir(&git_dir, &actor_id_hex);
22
23    let mut config = ActorConfig::new(actor_id, opts.label.clone());
24    let mut public_key = None;
25
26    if opts.generate_key {
27        let keypair = SigningKeyPair::generate();
28        public_key = Some(keypair.public_key_hex());
29
30        config.public_key = public_key.clone();
31        config.key_scheme = Some("ed25519".to_string());
32
33        std::fs::create_dir_all(&data_dir)?;
34        let signing_key_path = data_dir.join("signing_key");
35
36        #[cfg(unix)]
37        {
38            use std::fs::OpenOptions;
39            use std::io::Write;
40            use std::os::unix::fs::OpenOptionsExt;
41
42            let mut file = OpenOptions::new()
43                .write(true)
44                .create(true)
45                .truncate(true)
46                .mode(0o600)
47                .open(&signing_key_path)?;
48            file.write_all(keypair.seed_hex().as_bytes())?;
49        }
50
51        #[cfg(not(unix))]
52        {
53            std::fs::write(&signing_key_path, keypair.seed_hex())?;
54        }
55    }
56
57    save_actor_config(&data_dir, &config)?;
58
59    Ok(ActorInitResult {
60        actor_id: actor_id_hex,
61        label: opts.label.clone(),
62        data_dir,
63        public_key,
64    })
65}
66
67/// List all actors.
68pub fn actor_list() -> Result<ActorListResult, GriteError> {
69    let git_dir = GriteContext::find_git_dir()?;
70    let actors = list_actors(&git_dir)?;
71
72    Ok(ActorListResult { actors })
73}
74
75/// Show actor details.
76pub fn actor_show(
77    opts: &ActorShowOptions,
78    ctx: &GriteContext,
79) -> Result<ActorShowResult, GriteError> {
80    let actor_id = match &opts.id {
81        Some(id) => id.clone(),
82        None => ctx.actor_id.clone(),
83    };
84
85    let data_dir = actor_dir(&ctx.git_dir, &actor_id);
86    let config = load_actor_config(&data_dir)?;
87
88    Ok(ActorShowResult {
89        actor: config,
90        source: "".to_string(),
91    })
92}
93
94/// Show current actor.
95pub fn actor_current(ctx: &GriteContext) -> Result<ActorShowResult, GriteError> {
96    let data_dir = actor_dir(&ctx.git_dir, &ctx.actor_id);
97    let config = load_actor_config(&data_dir)?;
98
99    Ok(ActorShowResult {
100        actor: config,
101        source: ctx.source.as_str().to_string(),
102    })
103}
104
105/// Set the default actor.
106pub fn actor_use(opts: &ActorUseOptions) -> Result<(), GriteError> {
107    let git_dir = GriteContext::find_git_dir()?;
108
109    // Verify actor exists
110    let data_dir = actor_dir(&git_dir, &opts.id);
111    let _config = load_actor_config(&data_dir)?;
112
113    // Update repo config
114    let mut repo_config = load_repo_config(&git_dir)?.unwrap_or_default();
115    repo_config.default_actor = Some(opts.id.clone());
116
117    save_repo_config(&git_dir, &repo_config)?;
118
119    Ok(())
120}