diff --git a/Cargo.lock b/Cargo.lock index 3da0d8ca45..39d4e952f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1718,6 +1718,13 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "jj-docs" +version = "0.16.0" +dependencies = [ + "rust-embed", +] + [[package]] name = "jj-lib" version = "0.16.0" @@ -2561,6 +2568,41 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rust-embed" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb78f46d0066053d16d4ca7b898e9343bc3530f71c61d5ad84cd404ada068745" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91ac2a3c6c0520a3fb3dd89321177c3c692937c4eb21893378219da10c44fc8" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f69089032567ffff4eada41c573fc43ff466c7db7c5688b2e7969584345581" +dependencies = [ + "globset", + "sha2", + "walkdir", +] + [[package]] name = "rustc-demangle" version = "0.1.23" diff --git a/Cargo.toml b/Cargo.toml index 51040d8212..5fc5da80f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,14 @@ cargo-features = [] [workspace] resolver = "2" -members = ["cli", "lib", "lib/gen-protos", "lib/proc-macros", "lib/testutils"] +members = [ + "cli", + "lib", + "docs", + "lib/gen-protos", + "lib/proc-macros", + "lib/testutils", +] [workspace.package] version = "0.16.0" @@ -80,6 +87,7 @@ ref-cast = "1.0.22" regex = "1.10.3" rpassword = "7.3.1" rustix = { version = "0.38.32", features = ["fs"] } +rust-embed = { version = "8.3.0", features = ["include-exclude"] } scm-record = "0.2.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.115" @@ -116,6 +124,7 @@ zstd = "0.12.4" # put all inter-workspace libraries, i.e. those that use 'path = ...' here in # their own (alphabetically sorted) block +jj-docs = { path = "docs", version = "0.16.0" } jj-lib = { path = "lib", version = "0.16.0" } jj-lib-proc-macros = { path = "lib/proc-macros", version = "0.16.0" } testutils = { path = "lib/testutils" } diff --git a/docs/Cargo.toml b/docs/Cargo.toml new file mode 100644 index 0000000000..3feb38b063 --- /dev/null +++ b/docs/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "jj-docs" +description = "Documentation for Jujutsu - an experimental version control system" +autotests = false + +version = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +documentation = { workspace = true } +readme = { workspace = true } + +[lib] +path = "lib.rs" + +[dependencies] +rust-embed = { workspace = true } diff --git a/docs/lib.rs b/docs/lib.rs new file mode 100644 index 0000000000..4539af91ab --- /dev/null +++ b/docs/lib.rs @@ -0,0 +1,40 @@ +// Copyright 2024 The Jujutsu Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::borrow::Cow; + +#[derive(rust_embed::RustEmbed)] +#[folder = "."] +#[include = "*.md"] +struct DocAssetsMd; + +pub struct DocAssets; + +/// Documentation assets, allowing you to look up and iterate all the documents +/// available. +impl DocAssets { + // This is a simple wrapper around the `DocAssetsMd` + // struct that handles trimming off Markdown `.md` extensions, so that users + // can refer to documentation items without needing to know the file extension. + + /// Iterator. Returns all the documentation items available. + pub fn iter() -> impl Iterator { + DocAssetsMd::iter().map(|name| name.trim_end_matches(".md").to_owned()) + } + + pub fn get(name: &str) -> Option> { + // re-attach the `.md` extension before lookup + DocAssetsMd::get(&format!("{}.md", name)).map(|data| data.data) + } +}