Lindenii Project Forge
Login

hare-git

WIP Git library for Hare
Commit info
ID
0aca3bcfe7aaf83b22bdebceaf0209fa393d0c6b
Author
Runxi Yu <me@runxiyu.org>
Author date
Sun, 14 Sep 2025 03:24:22 +0800
Committer
Runxi Yu <me@runxiyu.org>
Committer date
Sun, 14 Sep 2025 03:32:58 +0800
Actions
Primitive tree-parsing function
use bytes;
use crypto::sha256;
use errors;
use strconv;
use strings;

export type tree = struct {
	oid: oid,
	entries: []tree_entry,
};
export fn tree_finish(t: tree) void = {
	for (let entry .. t.entries) {
		tree_entry_finish(entry);
	};
	free(t.entries);
};

export type tree_entry = struct {
	mode: u32,
	name: []u8,
	oid: oid,
};
export fn tree_entry_finish(te: tree_entry) void = {
	free(te.name);
};

export fn parse_tree(id: oid, body: []u8) (tree | errors::invalid | strconv::invalid | strconv::overflow | nomem) = {
	let entries: []tree_entry = [];
	let i = 0z;

	for (i < len(body)) {
		const sp = match (bytes::index(body[i..], ' ')) {
		case let j: size => yield j;
		case void => return errors::invalid;
		};
		const mode_b = body[i .. i+sp];
		i += sp + 1z;

		const nul = match (bytes::index(body[i..], 0u8)) {
		case let j: size => yield j;
		case void => return errors::invalid;
		};
		const name_b = body[i .. i+nul];
		i += nul + 1z;

		if (i + sha256::SZ > len(body)) return errors::invalid;
		let child: oid = [0...];
		child[..] = body[i .. i+sha256::SZ];
		i += sha256::SZ;

		const mode_s = strings::fromutf8_unsafe(mode_b);
		const mode = strconv::stou32(mode_s, strconv::base::OCT)?;

		const name = name_b[..];
		append(entries, tree_entry { mode = mode, name = name, oid = child })!;
	};

	return tree { oid = id, entries = entries };
};