darklua_core/frontend/
mod.rs1mod configuration;
2mod error;
3mod options;
4mod process_result;
5mod resources;
6mod utils;
7mod work_cache;
8mod work_item;
9mod worker;
10
11use std::path::Path;
12
13#[allow(unused_imports)]
14pub use configuration::{Configuration, GeneratorParameters, BundleConfiguration};
15pub use error::{DarkluaError, DarkluaResult};
16pub use options::Options;
17pub use process_result::ProcessResult;
18pub use resources::Resources;
19use serde::Serialize;
20use work_item::WorkItem;
21use worker::Worker;
22
23use crate::{
24 generator::{DenseLuaGenerator, LuaGenerator},
25 nodes::{Block, ReturnStatement},
26 process::to_expression,
27 utils::normalize_path,
28};
29
30pub fn process(resources: &Resources, options: Options) -> ProcessResult {
31 match private_process(resources, options) {
32 Ok(result) | Err(result) => result,
33 }
34}
35
36pub fn convert_data(value: impl Serialize) -> Result<String, DarkluaError> {
38 let expression = to_expression(&value).map_err(DarkluaError::from)?;
39
40 let block = Block::default()
41 .with_last_statement(ReturnStatement::default().with_expression(expression));
42
43 let mut generator = DenseLuaGenerator::default();
44 generator.write_block(&block);
45 Ok(generator.into_string())
46}
47
48fn private_process(
49 resources: &Resources,
50 options: Options,
51) -> Result<ProcessResult, ProcessResult> {
52 let worker = Worker::new(resources);
53
54 if let Some(output) = options.output().map(Path::to_path_buf) {
55 if resources.is_file(options.input())? {
56 if resources.is_directory(&output)? {
57 let file_name = options.input().file_name().ok_or_else(|| {
58 DarkluaError::custom(format!(
59 "unable to extract file name from `{}`",
60 options.input().display()
61 ))
62 })?;
63
64 worker.process(
65 once_ok(WorkItem::new(options.input(), output.join(file_name))),
66 options,
67 )
68 } else if resources.is_file(&output)? || output.extension().is_some() {
69 worker.process(once_ok(WorkItem::new(options.input(), output)), options)
70 } else {
71 let file_name = options.input().file_name().ok_or_else(|| {
72 DarkluaError::custom(format!(
73 "unable to extract file name from `{}`",
74 options.input().display()
75 ))
76 })?;
77
78 worker.process(
79 once_ok(WorkItem::new(options.input(), output.join(file_name))),
80 options,
81 )
82 }
83 } else {
84 let input = options.input().to_path_buf();
85
86 worker.process(
87 resources.collect_work(&input).map(|source| {
88 let source = normalize_path(source);
89 source
90 .strip_prefix(&input)
91 .map(|relative| WorkItem::new(&source, output.join(relative)))
92 .map_err(|err| {
93 DarkluaError::custom(format!(
94 "unable to remove path prefix `{}` from `{}`: {}",
95 input.display(),
96 source.display(),
97 err
98 ))
99 })
100 }),
101 options,
102 )
103 }
104 } else {
105 let input = options.input().to_path_buf();
106 worker.process(
107 resources
108 .collect_work(input)
109 .map(|source| Ok(WorkItem::new_in_place(source))),
110 options,
111 )
112 }
113}
114
115#[inline]
116fn once_ok<T, E>(value: T) -> impl Iterator<Item = Result<T, E>> {
117 std::iter::once(Ok(value))
118}