Radish alpha
r
rad:z39mP9rQAaGmERfUMPULfPUi473tY
Radicle terminal user interface
Radicle
Git
Misc patches
Merged did:key:z6MkwcUR...q1kL opened 8 months ago

Some misc patches I found possible when browsing the code

15 files changed +89 -136 a1060c98 16d3e7b4
modified bin/cob/inbox.rs
@@ -23,16 +23,9 @@ impl Default for SortBy {
}

pub fn all(repository: &Repository, profile: &Profile) -> Result<Vec<Notification>> {
-
    let all = profile
+
    profile
        .notifications_mut()?
        .by_repo(&repository.id, "timestamp")?
-
        .collect::<Vec<_>>();
-

-
    let mut notifications = vec![];
-
    for n in all {
-
        let n = n?;
-
        notifications.push(n);
-
    }
-

-
    Ok(notifications)
+
        .collect::<Result<Vec<_>, _>>()
+
        .map_err(anyhow::Error::from)
}
modified bin/commands/inbox.rs
@@ -197,7 +197,7 @@ pub async fn run(options: Options, ctx: impl terminal::Context) -> anyhow::Resul
    match options.op {
        Operation::List { opts } => {
            let profile = ctx.profile()?;
-
            let repository = profile.storage.repository(rid).unwrap();
+
            let repository = profile.storage.repository(rid)?;

            if let Err(err) = crate::log::enable() {
                println!("{err}");
modified bin/commands/issue.rs
@@ -111,7 +111,7 @@ impl Args for Options {
                    list_opts.mode = match val {
                        "operation" => common::Mode::Operation,
                        "id" => common::Mode::Id,
-
                        unknown => anyhow::bail!("unknown mode '{}'", unknown),
+
                        unknown => anyhow::bail!("unknown mode '{unknown}'"),
                    };
                }
                Long("all") if op == OperationName::List => {
@@ -200,7 +200,7 @@ pub async fn run(options: Options, ctx: impl terminal::Context) -> anyhow::Resul
        Operation::List { opts } => {
            let profile = ctx.profile()?;
            let rid = options.repo.unwrap_or(rid);
-
            let repository = profile.storage.repository(rid).unwrap();
+
            let repository = profile.storage.repository(rid)?;

            if let Err(err) = crate::log::enable() {
                println!("{err}");
@@ -226,16 +226,15 @@ pub async fn run(options: Options, ctx: impl terminal::Context) -> anyhow::Resul

                eprint!("{selection}");
            } else if let Some(selection) = selection {
-
                let mut args = vec![];
+
                let args = [
+
                    selection.operation.as_ref().cloned(),
+
                    selection.ids.first().map(ToString::to_string),
+
                ]
+
                .into_iter()
+
                .flatten()
+
                .map(OsString::from)
+
                .collect::<Vec<_>>();

-
                if let Some(operation) = selection.operation {
-
                    args.push(operation.to_string());
-
                }
-
                if let Some(id) = selection.ids.first() {
-
                    args.push(format!("{id}"));
-
                }
-

-
                let args = args.into_iter().map(OsString::from).collect::<Vec<_>>();
                let _ = crate::terminal::run_rad(Some("issue"), &args);
            }
        }
modified bin/commands/issue/list.rs
@@ -123,14 +123,7 @@ impl PreviewState {
            self.selected_comments
                .get(&item.id)
                .and_then(|selection| selection.last().copied())
-
                .and_then(|comment_id| {
-
                    item.comments
-
                        .iter()
-
                        .filter(|item| item.id == comment_id)
-
                        .collect::<Vec<_>>()
-
                        .first()
-
                        .cloned()
-
                })
+
                .and_then(|comment_id| item.comments.iter().find(|item| item.id == comment_id))
        })
    }

@@ -195,25 +188,27 @@ impl TryFrom<(&Context, &TerminalInfo)> for State {
        };

        // Convert into UI items
-
        let mut items = vec![];
-
        for issue in issues {
-
            if let Ok(item) = IssueItem::new(&context.profile, issue.clone()) {
-
                items.push(item);
-
            }
-
        }
+
        let mut items: Vec<_> = issues
+
            .into_iter()
+
            .flat_map(|issue| IssueItem::new(&context.profile, issue).ok())
+
            .collect();
+

        items.sort_by(|a, b| b.timestamp.cmp(&a.timestamp));

        // Pre-select first comment
-
        let mut selected_comments = HashMap::new();
-
        for item in &items {
-
            selected_comments.insert(
-
                item.id,
-
                item.root_comments()
+
        let selected_comments: HashMap<_, _> = items
+
            .iter()
+
            .map(|item| {
+
                let id = item.id;
+
                let comm = item
+
                    .root_comments()
                    .first()
-
                    .map(|comment| vec![comment.id])
-
                    .unwrap_or_default(),
-
            );
-
        }
+
                    .map(|c| vec![c.id])
+
                    .unwrap_or_default();
+

+
                (id, comm)
+
            })
+
            .collect();

        Ok(Self {
            mode: context.mode.clone(),
modified bin/commands/patch.rs
@@ -288,7 +288,7 @@ pub async fn run(options: Options, ctx: impl terminal::Context) -> anyhow::Resul
                    let mut args = vec![operation.to_string()];

                    if let Some(id) = selection.ids.first() {
-
                        args.push(format!("{id}"));
+
                        args.push(id.to_string());

                        match operation.as_str() {
                            "review" => {
@@ -382,7 +382,7 @@ mod interface {
        rid: RepoId,
        patch_id: PatchId,
    ) -> anyhow::Result<()> {
-
        let repo = profile.storage.repository(rid).unwrap();
+
        let repo = profile.storage.repository(rid)?;
        let signer = terminal::signer(&profile)?;

        let patch = patch::find(&profile, &repo, &patch_id)?
modified bin/commands/patch/list.rs
@@ -114,12 +114,13 @@ impl TryFrom<&Context> for State {
        let filter = PatchItemFilter::from_str(&context.filter.to_string()).unwrap_or_default();

        // Convert into UI items
-
        let mut items = vec![];
-
        for patch in patches {
-
            if let Ok(item) = PatchItem::new(&context.profile, &context.repository, patch.clone()) {
-
                items.push(item);
-
            }
-
        }
+
        let mut items: Vec<_> = patches
+
            .into_iter()
+
            .flat_map(|patch| {
+
                PatchItem::new(&context.profile, &context.repository, patch.clone()).ok()
+
            })
+
            .collect();
+

        items.sort_by(|a, b| b.timestamp.cmp(&a.timestamp));

        Ok(Self {
modified bin/commands/patch/list/imui.rs
@@ -112,12 +112,13 @@ impl TryFrom<&Context> for App {
        };
        let filter = PatchItemFilter::from_str(&context.filter.to_string()).unwrap_or_default();

-
        let mut items = vec![];
-
        for patch in patches {
-
            if let Ok(item) = PatchItem::new(&context.profile, &context.repository, patch.clone()) {
-
                items.push(item);
-
            }
-
        }
+
        let mut items = patches
+
            .into_iter()
+
            .flat_map(|patch| {
+
                PatchItem::new(&context.profile, &context.repository, patch.clone()).ok()
+
            })
+
            .collect::<Vec<_>>();
+

        items.sort_by(|a, b| b.timestamp.cmp(&a.timestamp));

        Ok(App {
modified bin/log.rs
@@ -21,7 +21,7 @@ pub fn enable() -> Result<(), anyhow::Error> {
            fs::create_dir_all(path.clone())?;

            simple_logging::log_to_file(
-
                format!("{}/{}{}.log", path, PREFIX, now.as_millis()),
+
                format!("{path}/{PREFIX}{}.log", now.as_millis()),
                LevelFilter::Info,
            )?;

modified bin/main.rs
@@ -174,8 +174,8 @@ fn print_help() -> anyhow::Result<()> {
fn run(command: Command) -> Result<(), Error> {
    match command {
        Command::Version { json } => {
-
            let mut stdout = io::stdout();
            if json {
+
                let mut stdout = io::stdout();
                VERSION.write_json(&mut stdout)?;
                println!();
            } else {
modified bin/state.rs
@@ -49,7 +49,7 @@ impl FileStore {
            Some(home) => format!("{}/{}", home.to_string_lossy(), PATH),
            _ => anyhow::bail!("Failed to read home directory"),
        };
-
        let path = format!("{}/{}.json", folder, filename.to_string());
+
        let path = format!("{folder}/{}.json", filename.to_string());

        fs::create_dir_all(folder.clone())?;

modified bin/ui/format.rs
@@ -55,22 +55,16 @@ pub fn patch_state(state: &patch::State) -> (String, Color) {
}

pub fn labels(labels: &[Label]) -> String {
-
    let mut output = String::new();
-
    let mut labels = labels.iter().peekable();
-

-
    while let Some(label) = labels.next() {
-
        output.push_str(&label.to_string());
-

-
        if labels.peek().is_some() {
-
            output.push_str(", ");
-
        }
-
    }
-
    output
+
    labels
+
        .iter()
+
        .map(|l| l.name())
+
        .collect::<Vec<_>>()
+
        .join(", ")
}

pub fn author(did: &Did, alias: &Option<Alias>, is_you: bool) -> String {
    let author = match alias {
-
        Some(alias) => format!("{alias}"),
+
        Some(alias) => alias.to_string(),
        None => self::did(did),
    };

@@ -82,17 +76,11 @@ pub fn author(did: &Did, alias: &Option<Alias>, is_you: bool) -> String {
}

pub fn assignees(assignees: &[(Option<PublicKey>, Option<Alias>, bool)]) -> String {
-
    let mut output = String::new();
-
    let mut assignees = assignees.iter().peekable();
-

-
    while let Some((assignee, alias, is_you)) = assignees.next() {
-
        if let Some(assignee) = assignee {
-
            output.push_str(&self::author(&Did::from(assignee), alias, *is_you));
-
        }
-

-
        if assignees.peek().is_some() {
-
            output.push(',');
-
        }
-
    }
-
    output
+
    assignees
+
        .iter()
+
        .flat_map(|(assignee, alias, is_you)| {
+
            assignee.map(|a| self::author(&Did::from(a), alias, *is_you))
+
        })
+
        .collect::<Vec<_>>()
+
        .join(",")
}
modified bin/ui/items.rs
@@ -459,9 +459,11 @@ impl FromStr for NotificationItemFilter {
                "is:branch" => type_name = Some(NotificationType::Branch),
                other => {
                    if let Ok((_, dids)) = authors_parser.parse(other) {
-
                        for did in dids {
-
                            authors.push(Did::from_str(did)?);
-
                        }
+
                        let dids = dids
+
                            .into_iter()
+
                            .map(Did::from_str)
+
                            .collect::<Result<Vec<_>, _>>()?;
+
                        authors.extend(dids);
                    } else {
                        search.push_str(other);
                    }
@@ -1009,10 +1011,7 @@ impl CommentItem {

impl ToTree<String> for CommentItem {
    fn rows(&self) -> Vec<TreeItem<'_, String>> {
-
        let mut children = vec![];
-
        for comment in &self.replies {
-
            children.extend(comment.rows());
-
        }
+
        let children = self.replies.iter().flat_map(CommentItem::rows).collect();

        let author = match &self.author.alias {
            Some(alias) => {
@@ -1706,16 +1705,9 @@ impl<'a> HunkItem<'a> {
                                    }

                                    // Add comment body
-
                                    rendered.extend(
-
                                        comment
-
                                            .1
-
                                            .body()
-
                                            .lines()
-
                                            .map(|line| {
-
                                                Line::from([span::default(line).gray()].to_vec())
-
                                            })
-
                                            .collect::<Vec<_>>(),
-
                                    );
+
                                    rendered.extend(comment.1.body().lines().map(|line| {
+
                                        Line::from([span::default(line).gray()].to_vec())
+
                                    }));

                                    // Add metadata
                                    rendered.push(
modified bin/ui/rm.rs
@@ -184,13 +184,7 @@ impl<S, M> View for IssueDetails<S, M> {

        if let Some(issue) = props.issue.as_ref() {
            let author = match &issue.author.alias {
-
                Some(alias) => {
-
                    if issue.author.you {
-
                        span::alias(&format!("{alias}"))
-
                    } else {
-
                        span::alias(alias)
-
                    }
-
                }
+
                Some(alias) => span::alias(alias.as_ref()),
                None => match &issue.author.human_nid {
                    Some(nid) => span::alias(nid).dim(),
                    None => span::blank(),
modified src/ui/rm/widget/window.rs
@@ -217,9 +217,11 @@ impl ShortcutsProps {

    pub fn shortcuts(mut self, shortcuts: &[(&str, &str)]) -> Self {
        self.shortcuts.clear();
-
        for (short, long) in shortcuts {
-
            self.shortcuts.push((short.to_string(), long.to_string()));
-
        }
+
        self.shortcuts.extend(
+
            shortcuts
+
                .iter()
+
                .map(|(s, l)| (s.to_string(), l.to_string())),
+
        );
        self
    }

modified src/ui/utils.rs
@@ -48,13 +48,14 @@ impl<T: Clone> LineMerger<T> {
                merged.push(line.clone());
            }

-
            if let Some(merges) = merge.get(&location) {
-
                for merge in merges {
-
                    for line in merge {
-
                        merged.push(line.clone());
-
                    }
-
                }
-
            }
+
            merged.extend(
+
                merge
+
                    .get(&location)
+
                    .into_iter()
+
                    .flatten()
+
                    .flat_map(|merge| merge.iter())
+
                    .cloned(),
+
            );

            if location == MergeLocation::Start {
                merged.push(line.clone());
@@ -96,7 +97,7 @@ Is this needed?
            HashMap::from([(MergeLocation::Line(2), vec![comment])]),
            Some(1),
        );
-
        let actual = build_string(merged);
+
        let actual = merged.join("\n");

        let expected = r#"
fn main() {
@@ -142,7 +143,7 @@ Is this needed?
            HashMap::from([(MergeLocation::Line(103), vec![comment])]),
            Some(100),
        );
-
        let actual = build_string(merged);
+
        let actual = merged.join("\n");

        let expected = r#"
fn main() {
@@ -164,17 +165,4 @@ fn another_function() {

        Ok(())
    }
-

-
    fn build_string(lines: Vec<&str>) -> String {
-
        let mut actual = String::new();
-
        for (idx, line) in lines.iter().enumerate() {
-
            if idx == lines.len() - 1 {
-
                actual.push_str(line);
-
            } else {
-
                actual.push_str(&format!("{line}\n"));
-
            }
-
        }
-

-
        actual
-
    }
}