{"id":13636650,"url":"https://github.com/ynqa/promkit","last_synced_at":"2025-05-14T23:07:02.091Z","repository":{"id":39834005,"uuid":"487447726","full_name":"ynqa/promkit","owner":"ynqa","description":"A toolkit for building interactive prompt in Rust","archived":false,"fork":false,"pushed_at":"2025-04-09T14:11:10.000Z","size":1070,"stargazers_count":383,"open_issues_count":10,"forks_count":9,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-14T14:59:39.196Z","etag":null,"topics":["cli","interactive","prompt","prompt-toolkit","readline","rust","terminal","tui"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/promkit","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ynqa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-05-01T04:49:46.000Z","updated_at":"2025-04-11T23:50:05.000Z","dependencies_parsed_at":"2023-07-14T08:55:35.090Z","dependency_job_id":"ff24828b-a96e-4e90-b372-19cfee93083e","html_url":"https://github.com/ynqa/promkit","commit_stats":{"total_commits":40,"total_committers":2,"mean_commits":20.0,"dds":"0.025000000000000022","last_synced_commit":"982fee20241eb7be6ccf64e01b8f5212066c8a49"},"previous_names":["ynqa/promptio"],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ynqa%2Fpromkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ynqa%2Fpromkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ynqa%2Fpromkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ynqa%2Fpromkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ynqa","download_url":"https://codeload.github.com/ynqa/promkit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243362,"owners_count":22038046,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","interactive","prompt","prompt-toolkit","readline","rust","terminal","tui"],"created_at":"2024-08-02T00:01:03.701Z","updated_at":"2025-05-14T23:06:57.073Z","avatar_url":"https://github.com/ynqa.png","language":"Rust","readme":"# promkit\n\n[![ci](https://github.com/ynqa/promkit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ynqa/promkit/actions/workflows/ci.yml)\n[![docs.rs](https://img.shields.io/docsrs/promkit)](https://docs.rs/promkit)\n\nA toolkit for building your own interactive prompt in Rust.\n\n## Getting Started\n\nPut the package in your `Cargo.toml`.\n\n```toml\n[dependencies]\npromkit = \"0.9.1\"\n```\n\n## Features\n\n- Cross-platform support for both UNIX and Windows utilizing [crossterm](https://github.com/crossterm-rs/crossterm)\n- Modularized architecture\n  - [promkit-core](https://github.com/ynqa/promkit/tree/v0.9.1/promkit-core/)\n    - Core functionality for basic terminal operations and pane management\n  - [promkit-widgets](https://github.com/ynqa/promkit/tree/v0.9.1/promkit-widgets/)\n    - Various UI components (text, listbox, tree, etc.)\n  - [promkit](https://github.com/ynqa/promkit/tree/v0.9.1/promkit)\n    - High-level presets and user interfaces\n  - [promkit-derive](https://github.com/ynqa/promkit/tree/v0.9.1/promkit-derive/)\n    - A Derive macro that simplifies interactive form input\n- Rich preset components\n  - [Readline](https://github.com/ynqa/promkit/tree/v0.9.1#readline) - Text input with auto-completion\n  - [Confirm](https://github.com/ynqa/promkit/tree/v0.9.1#confirm) - Yes/no confirmation prompt\n  - [Password](https://github.com/ynqa/promkit/tree/v0.9.1#password) - Password input with masking and validation\n  - [Form](https://github.com/ynqa/promkit/tree/v0.9.1#form) - Manage multiple text input fields\n  - [Listbox](https://github.com/ynqa/promkit/tree/v0.9.1#listbox) - Single selection interface from a list\n  - [QuerySelector](https://github.com/ynqa/promkit/tree/v0.9.1#queryselector) - Searchable selection interface\n  - [Checkbox](https://github.com/ynqa/promkit/tree/v0.9.1#checkbox) - Multiple selection checkbox interface\n  - [Tree](https://github.com/ynqa/promkit/tree/v0.9.1#tree) - Tree display for hierarchical data like file systems\n  - [JSON](https://github.com/ynqa/promkit/tree/v0.9.1#json) - Parse and interactively display JSON data\n  - [Text](https://github.com/ynqa/promkit/tree/v0.9.1#text) - Static text display\n\n## Concept\n\nSee [here](https://github.com/ynqa/promkit/tree/v0.9.1/Concept.md).\n\n## Projects using *promkit*\n\n- [ynqa/empiriqa](https://github.com/ynqa/empiriqa)\n- [ynqa/jnv](https://github.com/ynqa/jnv)\n- [ynqa/logu](https://github.com/ynqa/logu)\n- [ynqa/sig](https://github.com/ynqa/sig)\n\n## Examples/Demos\n\n*promkit* provides presets so that users can try prompts immediately without\nhaving to build complex components for specific use cases.\n\nShow you commands, code, and actual demo screens for examples\nthat can be executed immediately below.\n\n### Readline\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --bin readline --manifest-path examples/readline/Cargo.toml\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::{preset::readline::Readline, suggest::Suggest};\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let mut p = Readline::default()\n        .title(\"Hi!\")\n        .enable_suggest(Suggest::from_iter([\n            \"apple\",\n            \"applet\",\n            \"application\",\n            \"banana\",\n        ]))\n        .validator(\n            |text| text.len() \u003e 10,\n            |text| format!(\"Length must be over 10 but got {}\", text.len()),\n        )\n        .prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/d124268e-9496-4c4b-83be-c734e4d03591\" width=\"50%\" height=\"auto\"\u003e\n\n### Confirm\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --manifest-path examples/confirm/Cargo.toml\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::preset::confirm::Confirm;\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let mut p = Confirm::new(\"Do you have a pet?\").prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/ac9bac78-66cd-4653-a39f-6c9c0c24131f\" width=\"50%\" height=\"auto\"\u003e\n\n### Password\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --manifest-path examples/password/Cargo.toml\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::preset::password::Password;\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let mut p = Password::default()\n        .title(\"Put your password\")\n        .validator(\n            |text| 4 \u003c text.len() \u0026\u0026 text.len() \u003c 10,\n            |text| format!(\"Length must be over 4 and within 10 but got {}\", text.len()),\n        )\n        .prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/396356ef-47de-44bc-a8d4-d03c7ac66a2f\" width=\"50%\" height=\"auto\"\u003e\n\n### Form\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --manifest-path examples/form/Cargo.toml\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::{\n    crossterm::style::{Color, ContentStyle},\n    preset::form::Form,\n    promkit_widgets::text_editor,\n};\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let mut p = Form::new([\n        text_editor::State {\n            prefix: String::from(\"❯❯ \"),\n            prefix_style: ContentStyle {\n                foreground_color: Some(Color::DarkRed),\n                ..Default::default()\n            },\n            active_char_style: ContentStyle {\n                background_color: Some(Color::DarkCyan),\n                ..Default::default()\n            },\n            ..Default::default()\n        },\n        text_editor::State {\n            prefix: String::from(\"❯❯ \"),\n            prefix_style: ContentStyle {\n                foreground_color: Some(Color::DarkGreen),\n                ..Default::default()\n            },\n            active_char_style: ContentStyle {\n                background_color: Some(Color::DarkCyan),\n                ..Default::default()\n            },\n            ..Default::default()\n        },\n        text_editor::State {\n            prefix: String::from(\"❯❯ \"),\n            prefix_style: ContentStyle {\n                foreground_color: Some(Color::DarkBlue),\n                ..Default::default()\n            },\n            active_char_style: ContentStyle {\n                background_color: Some(Color::DarkCyan),\n                ..Default::default()\n            },\n            ..Default::default()\n        },\n    ])\n    .prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/c3dc88a7-d0f0-42f4-90b8-bc4d2e23e36d\" width=\"50%\" height=\"auto\"\u003e\n\n### Listbox\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --manifest-path examples/listbox/Cargo.toml\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::preset::listbox::Listbox;\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let mut p = Listbox::new(0..100)\n        .title(\"What number do you like?\")\n        .prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/0da1b1d0-bb17-4951-8ea8-3b09cd2eb86a\" width=\"50%\" height=\"auto\"\u003e\n\n### QuerySelector\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --manifest-path examples/query_selector/Cargo.toml\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::preset::query_selector::QuerySelector;\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let mut p = QuerySelector::new(0..100, |text, items| -\u003e Vec\u003cString\u003e {\n        text.parse::\u003cusize\u003e()\n            .map(|query| {\n                items\n                    .iter()\n                    .filter(|num| query \u003c= num.parse::\u003cusize\u003e().unwrap_or_default())\n                    .map(|num| num.to_string())\n                    .collect::\u003cVec\u003cString\u003e\u003e()\n            })\n            .unwrap_or(items.clone())\n    })\n    .title(\"What number do you like?\")\n    .listbox_lines(5)\n    .prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/7ac2ed54-9f9e-4735-bffb-72f7cee06f6d\" width=\"50%\" height=\"auto\"\u003e\n\n### Checkbox\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --manifest-path examples/checkbox/Cargo.toml\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::preset::checkbox::Checkbox;\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let mut p = Checkbox::new(vec![\n        \"Apple\",\n        \"Banana\",\n        \"Orange\",\n        \"Mango\",\n        \"Strawberry\",\n        \"Pineapple\",\n        \"Grape\",\n        \"Watermelon\",\n        \"Kiwi\",\n        \"Pear\",\n    ])\n    .title(\"What are your favorite fruits?\")\n    .checkbox_lines(5)\n    .prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/350b16ce-6ef4-46f2-9466-d01b9dab4eaf\" width=\"50%\" height=\"auto\"\u003e\n\n### Tree\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --manifest-path examples/tree/Cargo.toml\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::{preset::tree::Tree, promkit_widgets::tree::node::Node};\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let mut p = Tree::new(Node::try_from(\u0026std::env::current_dir()?.join(\"src\"))?)\n        .title(\"Select a directory or file\")\n        .tree_lines(10)\n        .prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/61aefcd0-080a-443e-9dc6-ac627d306f55\" width=\"50%\" height=\"auto\"\u003e\n\n### JSON\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand\u003c/summary\u003e\n\n```bash\ncargo run --manifest-path examples/json/Cargo.toml\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCode\u003c/summary\u003e\n\n```rust,ignore\nuse promkit::{\n    preset::json::Json,\n    promkit_widgets::{\n        jsonstream::JsonStream,\n        serde_json::{self, Deserializer},\n    },\n};\n\nfn main() -\u003e anyhow::Result\u003c()\u003e {\n    let stream = JsonStream::new(\n        Deserializer::from_str(\n            r#\"\n              {\n                \"apiVersion\": \"v1\",\n                \"kind\": \"Pod\",\n                \"metadata\": {\n                    \"annotations\": {\n                        \"kubeadm.kubernetes.io/etcd.advertise-client-urls\": \"https://172.18.0.2:2379\",\n                        \"kubernetes.io/config.hash\": \"9c4c3ba79af7ad68d939c568f053bfff\",\n                        \"kubernetes.io/config.mirror\": \"9c4c3ba79af7ad68d939c568f053bfff\",\n                        \"kubernetes.io/config.seen\": \"2024-10-12T12:53:27.751706220Z\",\n                        \"kubernetes.io/config.source\": \"file\"\n                    },\n                    \"creationTimestamp\": \"2024-10-12T12:53:31Z\",\n                    \"labels\": {\n                        \"component\": \"etcd\",\n                        \"tier\": \"control-plane\"\n                    },\n                    \"name\": \"etcd-kind-control-plane\",\n                    \"namespace\": \"kube-system\",\n                    \"ownerReferences\": [\n                        {\n                            \"apiVersion\": \"v1\",\n                            \"controller\": true,\n                            \"kind\": \"Node\",\n                            \"name\": \"kind-control-plane\",\n                            \"uid\": \"6cb2c3e5-1a73-4932-9cc5-6d69b80a9932\"\n                        }\n                    ],\n                    \"resourceVersion\": \"192988\",\n                    \"uid\": \"77465839-5a58-43b1-b754-55deed66d5ca\"\n                },\n                \"spec\": {\n                    \"containers\": [\n                        {\n                            \"command\": [\n                                \"etcd\",\n                                \"--advertise-client-urls=https://172.18.0.2:2379\",\n                                \"--cert-file=/etc/kubernetes/pki/etcd/server.crt\",\n                                \"--client-cert-auth=true\",\n                                \"--data-dir=/var/lib/etcd\",\n                                \"--experimental-initial-corrupt-check=true\",\n                                \"--experimental-watch-progress-notify-interval=5s\",\n                                \"--initial-advertise-peer-urls=https://172.18.0.2:2380\",\n                                \"--initial-cluster=kind-control-plane=https://172.18.0.2:2380\",\n                                \"--key-file=/etc/kubernetes/pki/etcd/server.key\",\n                                \"--listen-client-urls=https://127.0.0.1:2379,https://172.18.0.2:2379\",\n                                \"--listen-metrics-urls=http://127.0.0.1:2381\",\n                                \"--listen-peer-urls=https://172.18.0.2:2380\",\n                                \"--name=kind-control-plane\",\n                                \"--peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt\",\n                                \"--peer-client-cert-auth=true\",\n                                \"--peer-key-file=/etc/kubernetes/pki/etcd/peer.key\",\n                                \"--peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt\",\n                                \"--snapshot-count=10000\",\n                                \"--trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt\"\n                            ],\n                            \"image\": \"registry.k8s.io/etcd:3.5.15-0\",\n                            \"imagePullPolicy\": \"IfNotPresent\",\n                            \"livenessProbe\": {\n                                \"failureThreshold\": 8,\n                                \"httpGet\": {\n                                    \"host\": \"127.0.0.1\",\n                                    \"path\": \"/livez\",\n                                    \"port\": 2381,\n                                    \"scheme\": \"HTTP\"\n                                },\n                                \"initialDelaySeconds\": 10,\n                                \"periodSeconds\": 10,\n                                \"successThreshold\": 1,\n                                \"timeoutSeconds\": 15\n                            },\n                            \"name\": \"etcd\",\n                            \"readinessProbe\": {\n                                \"failureThreshold\": 3,\n                                \"httpGet\": {\n                                    \"host\": \"127.0.0.1\",\n                                    \"path\": \"/readyz\",\n                                    \"port\": 2381,\n                                    \"scheme\": \"HTTP\"\n                                },\n                                \"periodSeconds\": 1,\n                                \"successThreshold\": 1,\n                                \"timeoutSeconds\": 15\n                            },\n                            \"resources\": {\n                                \"requests\": {\n                                    \"cpu\": \"100m\",\n                                    \"memory\": \"100Mi\"\n                                }\n                            },\n                            \"startupProbe\": {\n                                \"failureThreshold\": 24,\n                                \"httpGet\": {\n                                    \"host\": \"127.0.0.1\",\n                                    \"path\": \"/readyz\",\n                                    \"port\": 2381,\n                                    \"scheme\": \"HTTP\"\n                                },\n                                \"initialDelaySeconds\": 10,\n                                \"periodSeconds\": 10,\n                                \"successThreshold\": 1,\n                                \"timeoutSeconds\": 15\n                            },\n                            \"terminationMessagePath\": \"/dev/termination-log\",\n                            \"terminationMessagePolicy\": \"File\",\n                            \"volumeMounts\": [\n                                {\n                                    \"mountPath\": \"/var/lib/etcd\",\n                                    \"name\": \"etcd-data\"\n                                },\n                                {\n                                    \"mountPath\": \"/etc/kubernetes/pki/etcd\",\n                                    \"name\": \"etcd-certs\"\n                                }\n                            ]\n                        }\n                    ],\n                    \"dnsPolicy\": \"ClusterFirst\",\n                    \"enableServiceLinks\": true,\n                    \"hostNetwork\": true,\n                    \"nodeName\": \"kind-control-plane\",\n                    \"preemptionPolicy\": \"PreemptLowerPriority\",\n                    \"priority\": 2000001000,\n                    \"priorityClassName\": \"system-node-critical\",\n                    \"restartPolicy\": \"Always\",\n                    \"schedulerName\": \"default-scheduler\",\n                    \"securityContext\": {\n                        \"seccompProfile\": {\n                            \"type\": \"RuntimeDefault\"\n                        }\n                    },\n                    \"terminationGracePeriodSeconds\": 30,\n                    \"tolerations\": [\n                        {\n                            \"effect\": \"NoExecute\",\n                            \"operator\": \"Exists\"\n                        }\n                    ],\n                    \"volumes\": [\n                        {\n                            \"hostPath\": {\n                                \"path\": \"/etc/kubernetes/pki/etcd\",\n                                \"type\": \"DirectoryOrCreate\"\n                            },\n                            \"name\": \"etcd-certs\"\n                        },\n                        {\n                            \"hostPath\": {\n                                \"path\": \"/var/lib/etcd\",\n                                \"type\": \"DirectoryOrCreate\"\n                            },\n                            \"name\": \"etcd-data\"\n                        }\n                    ]\n                },\n                \"status\": {\n                    \"conditions\": [\n                        {\n                            \"lastProbeTime\": null,\n                            \"lastTransitionTime\": \"2024-12-06T13:28:35Z\",\n                            \"status\": \"True\",\n                            \"type\": \"PodReadyToStartContainers\"\n                        },\n                        {\n                            \"lastProbeTime\": null,\n                            \"lastTransitionTime\": \"2024-12-06T13:28:34Z\",\n                            \"status\": \"True\",\n                            \"type\": \"Initialized\"\n                        },\n                        {\n                            \"lastProbeTime\": null,\n                            \"lastTransitionTime\": \"2024-12-06T13:28:50Z\",\n                            \"status\": \"True\",\n                            \"type\": \"Ready\"\n                        },\n                        {\n                            \"lastProbeTime\": null,\n                            \"lastTransitionTime\": \"2024-12-06T13:28:50Z\",\n                            \"status\": \"True\",\n                            \"type\": \"ContainersReady\"\n                        },\n                        {\n                            \"lastProbeTime\": null,\n                            \"lastTransitionTime\": \"2024-12-06T13:28:34Z\",\n                            \"status\": \"True\",\n                            \"type\": \"PodScheduled\"\n                        }\n                    ],\n                    \"containerStatuses\": [\n                        {\n                            \"containerID\": \"containerd://de0d57479a3ac10e213df6ea4fc1d648ad4d70d4ddf1b95a7999d0050171a41e\",\n                            \"image\": \"registry.k8s.io/etcd:3.5.15-0\",\n                            \"imageID\": \"sha256:27e3830e1402783674d8b594038967deea9d51f0d91b34c93c8f39d2f68af7da\",\n                            \"lastState\": {\n                                \"terminated\": {\n                                    \"containerID\": \"containerd://28d1a65bd9cfa40624a0c17979208f66a5cc7f496a57fa9a879907bb936f57b3\",\n                                    \"exitCode\": 255,\n                                    \"finishedAt\": \"2024-12-06T13:28:31Z\",\n                                    \"reason\": \"Unknown\",\n                                    \"startedAt\": \"2024-11-04T15:14:19Z\"\n                                }\n                            },\n                            \"name\": \"etcd\",\n                            \"ready\": true,\n                            \"restartCount\": 2,\n                            \"started\": true,\n                            \"state\": {\n                                \"running\": {\n                                    \"startedAt\": \"2024-12-06T13:28:35Z\"\n                                }\n                            }\n                        }\n                    ],\n                    \"hostIP\": \"172.18.0.2\",\n                    \"hostIPs\": [\n                        {\n                            \"ip\": \"172.18.0.2\"\n                        }\n                    ],\n                    \"phase\": \"Running\",\n                    \"podIP\": \"172.18.0.2\",\n                    \"podIPs\": [\n                        {\n                            \"ip\": \"172.18.0.2\"\n                        }\n                    ],\n                    \"qosClass\": \"Burstable\",\n                    \"startTime\": \"2024-12-06T13:28:34Z\"\n                }\n              }\n            \"#,\n        )\n        .into_iter::\u003cserde_json::Value\u003e()\n        .filter_map(serde_json::Result::ok)\n        .collect::\u003cVec\u003c_\u003e\u003e()\n        .iter(),\n    );\n\n    let mut p = Json::new(stream).title(\"JSON viewer\").prompt()?;\n    println!(\"result: {:?}\", p.run()?);\n    Ok(())\n}\n```\n\u003c/details\u003e\n\n\u003cimg src=\"https://github.com/ynqa/promkit/assets/6745370/751af3ae-5aff-45ca-8729-34cd004ee7d9\" width=\"50%\" height=\"auto\"\u003e\n\n## License\n\nThis project is licensed under the MIT License.\nSee the [LICENSE](https://github.com/ynqa/promkit/blob/main/LICENSE)\nfile for details.\n\n## Stargazers over time\n[![Stargazers over time](https://starchart.cc/ynqa/promkit.svg?variant=adaptive)](https://starchart.cc/ynqa/promkit)\n","funding_links":[],"categories":["Rust","Libraries","库 Libraries"],"sub_categories":["Command-line","命令行 Command-line"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fynqa%2Fpromkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fynqa%2Fpromkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fynqa%2Fpromkit/lists"}