1#[derive(Debug)]
7pub struct SassContext<S: DataOrFileSassContextMutPointer>(S, Rc<SassFunctionList>, Rc<SassImporterList>, Rc<SassImporterList>);
8
9impl<S: DataOrFileSassContextMutPointer> Drop for SassContext<S>
10{
11 #[inline(always)]
12 fn drop(&mut self)
13 {
14 self.0.delete()
15 }
16}
17
18impl<S: DataOrFileSassContextMutPointer> SassContext<S>
19{
20 #[inline(always)]
22 pub fn new_with_data<'p, P: AsRef<Path>>(sass_input_data: &str, useful_sass_options: &SassOptions<'p, P>) -> SassContext<*mut Sass_Data_Context>
23 {
24 let source_string = CString::new(sass_input_data).unwrap();
25 let data_context = unsafe { sass_make_data_context(sass_copy_c_string(source_string.as_ptr())) };
26 Self::finish_new(data_context, useful_sass_options)
27 }
28
29 #[inline(always)]
31 pub fn new_with_file<'p, P: AsRef<Path>>(sass_input_file_path: P, useful_sass_options: &SassOptions<'p, P>) -> SassContext<*mut Sass_File_Context>
32 {
33 #[cfg(windows)]
34 {
35 let c_string = CString::new(sass_input_file_path.as_ref().to_str().unwrap()).unwrap();
36 let pointer = c_string.as_ptr();
37 Self::finish_new(unsafe { sass_make_file_context(pointer) }, useful_sass_options)
38 }
39
40 #[cfg(not(windows))]
41 {
42 use ::std::os::unix::ffi::OsStrExt;
43 let bytes = sass_input_file_path.as_ref().as_os_str().as_bytes();
44
45 let pointer = bytes.as_ptr() as *const c_char;
46
47 Self::finish_new(unsafe { sass_make_file_context(pointer) }, useful_sass_options)
48 }
49 }
50
51 #[inline(always)]
52 fn finish_new<'p, P: AsRef<Path>, S2: DataOrFileSassContextMutPointer>(data_or_file_context: S2, useful_sass_options: &SassOptions<'p, P>) -> SassContext<S2>
53 {
54 let options = data_or_file_context.get_options();
55
56 options.set_output_style(useful_sass_options.output_style);
57
58 options.set_source_comments(useful_sass_options.source_comments);
59
60 options.set_source_map_embed(useful_sass_options.source_map_embed);
61
62 options.set_source_map_contents(useful_sass_options.source_map_contents);
63
64 options.set_source_map_file_urls(useful_sass_options.source_map_file_urls);
65
66 options.set_omit_source_map_url(useful_sass_options.omit_source_map_url);
67
68 if !useful_sass_options.indent.to_bytes().is_empty()
69 {
70 options.set_indent(&useful_sass_options.indent)
71 }
72
73 if !useful_sass_options.linefeed.to_bytes().is_empty()
74 {
75 options.set_linefeed(&useful_sass_options.linefeed)
76 }
77
78 options.set_precision(useful_sass_options.precision);
79
80 if useful_sass_options.input_syntax == InputSyntax::SASS
81 {
82 options.set_is_indented_syntax_src();
83 }
84
85 options.set_include_path(useful_sass_options.include_paths);
86
87 useful_sass_options.function_list.set_functions_on_options(options);
88
89 useful_sass_options.importer_list.set_importers_on_options(options);
90
91 useful_sass_options.header_list.set_headers_on_options(options);
92
93 SassContext(data_or_file_context, useful_sass_options.function_list.clone(), useful_sass_options.importer_list.clone(), useful_sass_options.header_list.clone())
94 }
95
96 pub fn compile(&self) -> Result<String, SassCompileError>
98 {
99 self.0.compile();
100 let context = self.0.get_context();
101
102 let error_status = context.get_error_status();
103 if error_status == 0
104 {
105 if let Some(output_string) = context.get_output_string()
106 {
107 let css_utf8_string = output_string.to_str()?;
108 Ok(css_utf8_string.to_owned())
109 }
110 else
111 {
112 panic!("No error, but CSS output string is null");
113 }
114 }
115 else
116 {
117 if let Some(error_message) = context.get_error_message()
118 {
119 Err(SassCompileError::Known(error_message.to_owned()))
120 }
121 else
122 {
123 Err(SassCompileError::Unknown)
124 }
125 }
126 }
127}