Skip to content

Dev #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 23, 2025
Merged

Dev #20

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 63 additions & 32 deletions .github/doc/doc.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,93 @@
#!/usr/bin/env python3

"""
Multi-version Rust documentation for GitHub Pages.

- Generates documentation for default branch and for the given Git ref.
- Generates index.html, for each ref, to redirect to crate documentation.
- Generates main index.html that lists all versions (only semver Git tag) + default branch (skips anything else).

Usage:
./doc.py [ref]

If no ref is provided, it defaults to using "master".
"""

import re
import shutil
import subprocess
import sys
from pathlib import Path


def clean(docs: Path, ghpages: Path):
def clean(docs: Path, gh_pages: Path):
"""Remove and recreate documentation directories."""
shutil.rmtree(docs, ignore_errors=True)
shutil.rmtree(ghpages, ignore_errors=True)
shutil.rmtree(gh_pages, ignore_errors=True)
docs.mkdir(parents=True)


def main(current_ref: str):
docs = Path("target/docs")
build = Path("target/docs_build")
redirect_template = Path(".github/doc/index_redirect.html")
template = Path(".github/doc/index_template.html")
version_template = Path(".github/doc/version_template.html")
gh_pages_path = Path("target/gh-pages")

clean(docs, gh_pages_path)

# Copy existing versions from gh-pages
cmd(f"git worktree add {gh_pages_path} gh-pages -f")
def copy_existing_versions(gh_pages: Path, docs: Path):
"""Copy existing versioned documentation from gh-pages to docs."""
run_cmd(f"git worktree add {gh_pages} gh-pages -f")

for item in gh_pages_path.iterdir():
for item in gh_pages.iterdir():
if item.is_dir():
shutil.copytree(item, docs / item.name)

# Generate docs for current_ref
print(f"Generating docs for {current_ref}...")
cmd(f"git checkout {current_ref}")
cmd(f"cargo doc --no-deps --target-dir={build}")

(docs / current_ref).mkdir(parents=True, exist_ok=True)
def generate_docs(build: Path, docs: Path, git_ref: str, redirect_template: Path):
"""Generate documentation for the given Git reference."""
print(f"Generating docs for {git_ref}...")
run_cmd(f"git checkout {git_ref}")
run_cmd(f"cargo doc --no-deps --target-dir={build}")

(docs / git_ref).mkdir(parents=True, exist_ok=True)
build_doc = build / "doc"
shutil.copytree(build_doc, docs / current_ref, dirs_exist_ok=True)
shutil.copy2(redirect_template, docs / current_ref / "index.html")
shutil.copytree(build_doc, docs / git_ref, dirs_exist_ok=True)
shutil.copy2(redirect_template, docs / git_ref / "index.html")

# Load templates
version_tpl = version_template.read_text()
template_text = template.read_text()

# Prepare refs list: master + tags sorted descending semver
tags = cmd("git tag").splitlines()
def get_version_refs() -> list[str]:
"""Get a list of version refs: sorted tags."""
tags = run_cmd("git tag").splitlines()
tags.sort(reverse=True, key=lambda s: list(map(int, s.lstrip("v").split("."))))
refs = ["master"] + tags
return tags


def generate_main_index(
docs: Path, version_template: Path, index_template: Path, refs: list[str]
):
"""Generate the main index.html for the docs site."""
version_tpl = version_template.read_text()
index_tpl = index_template.read_text()

# Generate main index.html
version_list = ""
for ver in refs:
version_list += version_tpl.format(version=ver)

index_html = template_text.format(versions=version_list)
index_html = index_tpl.format(versions=version_list)
index_html = re.sub(r" +", " ", index_html.replace("\n", ""))
(docs / "index.html").write_text(index_html)


def cmd(cmd: str):
def main(ref: str, default_ref: str):
docs = Path("target/docs")
build = Path("target/docs_build")
redirect_template = Path(".github/doc/index_redirect.html")
index_template = Path(".github/doc/index_template.html")
version_template = Path(".github/doc/version_template.html")
gh_pages = Path("target/gh-pages")

clean(docs, gh_pages)
copy_existing_versions(gh_pages, docs)
generate_docs(build, docs, ref, redirect_template)

refs = [default_ref] + get_version_refs()
generate_main_index(docs, version_template, index_template, refs)


def run_cmd(cmd: str):
result = subprocess.run(
cmd.split(),
stdout=subprocess.PIPE,
Expand All @@ -70,7 +100,8 @@ def cmd(cmd: str):

if __name__ == "__main__":
try:
main(sys.argv[1] if len(sys.argv) > 1 else "master")
default_branch = "master"
main(sys.argv[1] if len(sys.argv) > 1 else default_branch, default_branch)
except subprocess.CalledProcessError as e:
print(e.stderr)
sys.exit(1)
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt
- run: cargo fmt --all -- --check
- run: cargo +nightly fmt --all -- --check

clippy:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ test:
cargo test

fmt:
cargo fmt --all -- --check || (cargo fmt --all && exit 1)
cargo +nightly fmt --all -- --check || (cargo +nightly fmt --all && exit 1)

lint:
cargo clippy --all-targets --all-features
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@ See more examples in the documentation of [`Vec`].

## Development on Linux

See [Makefile](https://github.com/andreiavrammsd/static_vector.rs/blob/master/Makefile).
* Install [Rust](https://www.rust-lang.org/tools/install) (stable is used for main code, nightly is used only for code formatting and fuzz tests).
* If using VS Code, see [setup](https://github.com/andreiavrammsd/static_vector.rs/tree/master/.vscode).
* See [Makefile](https://github.com/andreiavrammsd/static_vector.rs/blob/master/Makefile).
5 changes: 5 additions & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
style_edition = "2024"
group_imports = "StdExternalCrate"
imports_granularity = "Module"
format_code_in_doc_comments = true
use_field_init_shorthand = true
max_width = 100
hard_tabs = false
use_small_heuristics = "Max"
Expand Down
29 changes: 15 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
#![deny(missing_docs)]
#![doc = include_str!("../README.md")]

use core::{error, fmt, mem::MaybeUninit, slice};
use core::mem::MaybeUninit;
use core::{error, fmt, slice};

/// Error for when the vector is full or the requested operation would need more space than the capacity.
///
Expand Down Expand Up @@ -72,7 +73,7 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
///
/// let vec = Vec::<i32, 10>::new();
/// const SOME_LIMIT: usize = 5;
///
///
/// if vec.len() < vec.capacity() - SOME_LIMIT {
/// // do something
/// }
Expand Down Expand Up @@ -236,7 +237,7 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
///
/// #[derive(Debug)]
/// enum AppError {
/// MyFnError
/// MyFnError,
/// }
///
/// fn my_fn(vec: &mut Vec<i32, 200>) -> Result<(), AppError> {
Expand Down Expand Up @@ -290,7 +291,7 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
/// use static_vector::Vec;
///
/// let mut vec = Vec::<i32, 20>::new();
///
///
/// match vec.first() {
/// Some(num) => {
/// let _ = num;
Expand All @@ -315,10 +316,10 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
/// use static_vector::Vec;
///
/// let mut vec = Vec::<i32, 20>::new();
///
///
/// if let Some(num) = vec.first_mut() {
/// *num = 1;
/// let _ = num;
/// *num = 1;
/// let _ = num;
/// }
/// ```
#[must_use]
Expand All @@ -336,7 +337,7 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
/// use static_vector::Vec;
///
/// let mut vec = Vec::<i32, 30>::new();
///
///
/// if let Some(num) = vec.last() {
/// let _ = num;
/// // do something with the last element
Expand All @@ -359,8 +360,8 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
/// let mut vec = Vec::<i32, 20>::new();
///
/// if let Some(num) = vec.last_mut() {
/// *num = 1;
/// let _ = num;
/// *num = 1;
/// let _ = num;
/// }
/// ```
#[must_use]
Expand All @@ -378,7 +379,7 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
/// use static_vector::Vec;
///
/// let mut vec = Vec::<i32, 20>::new();
///
///
/// match vec.get(22) {
/// Some(num) => {
/// let _ = num;
Expand Down Expand Up @@ -410,7 +411,7 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
/// use static_vector::Vec;
///
/// let mut vec = Vec::<i32, 20>::new();
///
///
/// if vec.push(1).is_ok() {
/// *vec.get_mut(0).unwrap() = 5;
/// }
Expand Down Expand Up @@ -524,7 +525,7 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
/// let mut vec = Vec::<i32, 20>::new();
///
/// for num in vec.iter_mut() {
/// *num *= 2;
/// *num *= 2;
/// }
/// ```
#[inline]
Expand Down Expand Up @@ -570,7 +571,7 @@ impl<T, const CAPACITY: usize> Vec<T, CAPACITY> {
/// use static_vector::Vec;
///
/// let mut vec = Vec::<i32, 10>::new();
///
///
/// if vec.set_len(5).is_ok() {
/// vec.as_mut_slice().fill(1);
/// } else {
Expand Down