-
Notifications
You must be signed in to change notification settings - Fork 659
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
851 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { parseCrate, crateResolver } from './parser'; | ||
import { generatePage } from './generator'; | ||
import { join, dirname } from 'node:path'; | ||
import { fileURLToPath } from 'node:url'; | ||
|
||
// IMPORTANT: Keep these up to date and correct | ||
const baseUrl = '/2/reference/core/rust'; | ||
const rootDir = dirname(dirname(dirname(fileURLToPath(import.meta.url)))); | ||
const docsPath = join(rootDir, 'src', 'content', 'docs', '2', 'reference', 'core', 'rust'); | ||
const documentCrates = [ | ||
'tauri', | ||
'tauri-build', | ||
'tauri-codegen', | ||
'tauri-macros', | ||
'tauri-runtime', | ||
'tauri-runtime-wry', | ||
'tauri-utils', | ||
]; | ||
|
||
async function main() { | ||
console.log('Starting'); | ||
for (const crate of documentCrates) { | ||
console.log(`Documenting crate: ${crate}`); | ||
const rustdoc = await crateResolver(crate); | ||
if (!rustdoc) { | ||
console.error(`Crate could not be resolved: ${crate}`); | ||
continue; | ||
} | ||
const pages = await parseCrate(rustdoc, `${baseUrl}/${crate}/`, join(docsPath, crate)); | ||
for (const page of pages) { | ||
console.log(`Generating page: ${page.path}`); | ||
await generatePage(page); | ||
} | ||
} | ||
} | ||
|
||
main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import type { Page, PageContent, PageType } from './types'; | ||
import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync } from 'node:fs'; | ||
import { join, dirname } from 'node:path'; | ||
|
||
/** | ||
* Write a single page to disk | ||
*/ | ||
export async function generatePage(page: Page) { | ||
mkdirSync(dirname(page.path), { recursive: true }); | ||
writeFileSync(page.path, page.content); | ||
} | ||
|
||
/** | ||
* Generates content for a page | ||
* | ||
* @param type | ||
* @returns | ||
*/ | ||
export async function generateContent(type: PageType, content: PageContent): Promise<string> { | ||
switch (type) { | ||
case 'crate': | ||
return await generateContentModule(content, true); | ||
case 'module': | ||
return await generateContentModule(content); | ||
case 'struct': | ||
return await generateContentStruct(content); | ||
default: | ||
throw Error('Unknown content type'); | ||
} | ||
} | ||
|
||
function header(title: string): string { | ||
return `--- | ||
title: '${title}' | ||
editUrl: false | ||
prev: false | ||
next: false | ||
--- | ||
`; | ||
} | ||
|
||
function fixDocs(docs: undefined | null | string): string { | ||
if (!docs) return ''; | ||
return docs.split('\n')[0]; | ||
} | ||
|
||
function members(content: PageContent): string { | ||
const output: string[] = []; | ||
const modules = content.members.filter((val) => 'module' in val.item.inner); | ||
if (modules.length > 0) output.push('## Modules\n\n'); | ||
for (const member of modules) { | ||
output.push( | ||
`- [${member.item.name}](${content.moduleUrl}${member.path.path | ||
.slice(1) | ||
.join('/')}): ${fixDocs(member.item.docs)}` | ||
); | ||
} | ||
const structs = content.members.filter((val) => 'struct' in val.item.inner); | ||
if (structs.length > 0) output.push('## Structs\n\n'); | ||
for (const member of structs) { | ||
output.push( | ||
`- [${member.item.name}](${content.moduleUrl}${member.item.name}): ${fixDocs( | ||
member.item.docs | ||
)}` | ||
); | ||
} | ||
return output.join('\n'); | ||
} | ||
|
||
/** | ||
* Generates content for either a crate or a module, they are virtually identical | ||
* | ||
* @param isCrate | ||
* @returns | ||
*/ | ||
export async function generateContentModule( | ||
content: PageContent, | ||
isCrate: boolean = false | ||
): Promise<string> { | ||
return `${header((isCrate ? 'Crate' : 'Module') + ' ' + content.title)} | ||
${content.description} | ||
${members(content)}`; | ||
} | ||
|
||
/** | ||
* Generates content for a struct | ||
* | ||
* @returns | ||
*/ | ||
export async function generateContentStruct(content: PageContent): Promise<string> { | ||
return ''; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "rust-api-generator", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"build": "tsm ./build.ts" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"tsm": "^2.3.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import type { RustDoc, Page, PageMember, ID } from './types'; | ||
import { PageMemberType, PageType } from './types/pages'; | ||
import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync } from 'node:fs'; | ||
import { join, dirname } from 'node:path'; | ||
import { fileURLToPath } from 'node:url'; | ||
import { generateContent } from './generator'; | ||
|
||
async function parseModules( | ||
rootPath: string, | ||
baseUrl: string, | ||
rustdoc: RustDoc, | ||
isCrate: boolean = false | ||
): Promise<Page[]> { | ||
const pages: Page[] = []; | ||
if (isCrate) { | ||
const item = rustdoc.index[rustdoc.root]; | ||
const path = rustdoc.paths[rustdoc.root]; | ||
const members: PageMember[] = item.inner.module.items.map((id: ID) => { | ||
const member: PageMember = { | ||
type: PageMemberType.struct, | ||
item: rustdoc.index[id], | ||
path: rustdoc.paths[id], | ||
}; | ||
return member; | ||
}); | ||
pages.push({ | ||
type: PageType.crate, | ||
path: join(rootPath, path.path.slice(1).join('/'), 'index.md'), | ||
content: await generateContent(PageType.crate, { | ||
title: path.path.join('::'), | ||
description: item.docs ?? '', | ||
moduleUrl: baseUrl, | ||
members: members, | ||
}), | ||
}); | ||
} else { | ||
for (const id in rustdoc.paths) { | ||
const path = rustdoc.paths[id]; | ||
if (path.kind !== 'module' || path.crate_id !== 0 || id === rustdoc.root) continue; | ||
const item = rustdoc.index[id]; | ||
const members: PageMember[] = item.inner.module.items.map((id: ID) => { | ||
const member: PageMember = { | ||
type: PageMemberType.struct, | ||
item: rustdoc.index[id], | ||
path: rustdoc.paths[id], | ||
}; | ||
return member; | ||
}); | ||
pages.push({ | ||
type: PageType.module, | ||
path: join(rootPath, path.path.slice(1).join('/'), 'index.md'), | ||
content: await generateContent(PageType.module, { | ||
title: path.path.join('::'), | ||
description: item.docs ?? '', | ||
moduleUrl: baseUrl, | ||
members: members, | ||
}), | ||
}); | ||
} | ||
} | ||
return pages; | ||
} | ||
|
||
async function parseStructs(rootPath: string, baseUrl: string, rustdoc: RustDoc): Promise<Page[]> { | ||
const pages: Page[] = []; | ||
return pages; | ||
} | ||
|
||
/** | ||
* Parses a single JSON file | ||
*/ | ||
export async function parseCrate( | ||
rustdoc: RustDoc, | ||
baseUrl: string, | ||
rootPath: string | ||
): Promise<Page[]> { | ||
let pages: Page[] = []; | ||
const crateItem = rustdoc.index[rustdoc.root]; | ||
|
||
for (const type in PageType) { | ||
switch (type) { | ||
case 'crate': | ||
pages = pages.concat(await parseModules(rootPath, baseUrl, rustdoc, true)); | ||
case 'module': | ||
pages = pages.concat(await parseModules(rootPath, baseUrl, rustdoc)); | ||
case 'struct': | ||
pages = pages.concat(await parseStructs(rootPath, baseUrl, rustdoc)); | ||
} | ||
} | ||
return pages; | ||
} | ||
|
||
/** | ||
* Resolves the path to a json file for external crates | ||
* @param crate | ||
*/ | ||
export async function crateResolver(crate: string): Promise<RustDoc | null> { | ||
const targetFolder = '../tauri/target'; | ||
for (const file of readdirSync(targetFolder)) { | ||
if (file !== crate + '.json') continue; | ||
|
||
const rustdoc: RustDoc = JSON.parse(readFileSync(join(targetFolder, file), 'utf-8')); | ||
rustdoc.name = crate; | ||
return rustdoc; | ||
} | ||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './rustdoc'; | ||
export * from './pages'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import type { Item, ItemSummary } from './rustdoc'; | ||
|
||
/** | ||
* A `Page` to be rendered | ||
*/ | ||
export interface Page { | ||
/** | ||
* The type of the page | ||
*/ | ||
type: PageType; | ||
/** | ||
* Path to the page .md file | ||
*/ | ||
path: string; | ||
/** | ||
* Contents of the page | ||
*/ | ||
content: string; | ||
} | ||
|
||
/** | ||
* Page content used for templating | ||
*/ | ||
export interface PageContent { | ||
/** | ||
* Page title | ||
*/ | ||
title: string; | ||
/** | ||
* URL to the page | ||
*/ | ||
moduleUrl: string; | ||
/** | ||
* Page description | ||
*/ | ||
description: string; | ||
/** | ||
* Member items of this page | ||
*/ | ||
members: PageMember[]; | ||
} | ||
|
||
export interface PageMember { | ||
type: PageMemberType; | ||
item: Item; | ||
path: ItemSummary; | ||
} | ||
|
||
/** | ||
* The type of the page | ||
*/ | ||
export enum PageMemberType { | ||
'module' = 'module', | ||
'struct' = 'struct', | ||
} | ||
|
||
/** | ||
* The type of the page | ||
*/ | ||
export enum PageType { | ||
'crate' = 'crate', | ||
'module' = 'module', | ||
'struct' = 'struct', | ||
} |
Oops, something went wrong.