next_napi_bindings/
code_frame.rs1use napi::bindgen_prelude::*;
2use napi_derive::napi;
3use next_code_frame::{CodeFrameLocation, CodeFrameOptions, Language, Location, render_code_frame};
4
5const DEFAULT_MAX_WIDTH: u32 = 100;
7
8#[napi(object)]
9pub struct NapiLocation {
10 pub line: u32,
11 pub column: Option<u32>,
12}
13
14impl From<NapiLocation> for Location {
15 fn from(loc: NapiLocation) -> Self {
16 Location {
17 line: loc.line as usize,
18 column: loc.column.map(|c| c as usize),
19 }
20 }
21}
22
23#[napi(object)]
24pub struct NapiCodeFrameLocation {
25 pub start: NapiLocation,
26 pub end: Option<NapiLocation>,
27}
28
29impl From<NapiCodeFrameLocation> for CodeFrameLocation {
30 fn from(loc: NapiCodeFrameLocation) -> Self {
31 CodeFrameLocation {
32 start: loc.start.into(),
33 end: loc.end.map(Into::into),
34 }
35 }
36}
37
38#[napi(object)]
39#[derive(Default)]
40pub struct NapiCodeFrameOptions {
41 pub lines_above: Option<u32>,
43 pub lines_below: Option<u32>,
45 pub max_width: Option<u32>,
47 pub color: Option<bool>,
49 pub highlight_code: Option<bool>,
55 pub message: Option<String>,
57 pub language: Option<String>,
59}
60
61fn parse_language(s: &Option<String>) -> Language {
62 match s.as_deref() {
63 Some("css") => Language::Css,
64 _ => Language::JavaScript,
65 }
66}
67
68impl From<NapiCodeFrameOptions> for CodeFrameOptions {
69 fn from(opts: NapiCodeFrameOptions) -> Self {
70 CodeFrameOptions {
71 lines_above: opts.lines_above.unwrap_or(2) as usize,
72 lines_below: opts.lines_below.unwrap_or(3) as usize,
73 max_width: opts.max_width.unwrap_or(DEFAULT_MAX_WIDTH) as usize,
74 color: opts.color.unwrap_or(false),
75 highlight_code: opts.highlight_code.unwrap_or(opts.color.unwrap_or(false)),
76 message: opts.message,
77 language: parse_language(&opts.language),
78 }
79 }
80}
81
82#[napi]
98pub fn code_frame_columns(
99 source: String,
100 location: NapiCodeFrameLocation,
101 options: Option<NapiCodeFrameOptions>,
102) -> Result<Option<String>> {
103 let code_frame_location: CodeFrameLocation = location.into();
104 let code_frame_options: CodeFrameOptions = options.unwrap_or_default().into();
105
106 render_code_frame(&source, &code_frame_location, &code_frame_options)
107 .map_err(|e| Error::from_reason(format!("Failed to render code frame: {e:?}")))
108}