sass_alt/
SassContext.rs

1// This file is part of sass-alt. It is subject to the license terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/sass-alt/master/COPYRIGHT. No part of predicator, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
2// Copyright © 2017 The developers of sass-alt. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/sass-alt/master/COPYRIGHT.
3
4
5/// Wraps a SASS data or file context and holds a list of function used by that context.
6#[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	/// Creates a new SassContext from data and options.
21	#[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	/// Creates a new SassContext from a file and options.
30	#[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	/// Compiles SASS data.
97	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}