1use crate::context_handle::with_context;
2use crate::enums::CapStyle;
3use crate::functions::{errcheck, nullcheck};
4use crate::traits::as_raw_mut_impl;
5use crate::{AsRaw, AsRawMut, GResult, JoinStyle};
6use geos_sys::*;
7use std::ptr::NonNull;
8
9pub struct BufferParams {
11 ptr: NonNull<GEOSBufferParams>,
12}
13
14#[derive(Default)]
16pub struct BufferParamsBuilder {
17 end_cap_style: Option<CapStyle>,
18 join_style: Option<JoinStyle>,
19 mitre_limit: Option<f64>,
20 quadrant_segments: Option<i32>,
21 single_sided: Option<bool>,
22}
23
24impl BufferParams {
25 pub fn new() -> GResult<Self> {
26 with_context(|ctx| unsafe {
27 let ptr = nullcheck!(GEOSBufferParams_create_r(ctx.as_raw()))?;
28 Ok(Self { ptr })
29 })
30 }
31
32 pub fn builder() -> BufferParamsBuilder {
33 BufferParamsBuilder::default()
34 }
35
36 pub fn set_end_cap_style(&mut self, style: CapStyle) -> GResult<()> {
38 with_context(|ctx| unsafe {
39 errcheck!(GEOSBufferParams_setEndCapStyle_r(
40 ctx.as_raw(),
41 self.as_raw_mut_override(),
42 style.into(),
43 ))?;
44 Ok(())
45 })
46 }
47
48 pub fn set_join_style(&mut self, style: JoinStyle) -> GResult<()> {
50 with_context(|ctx| unsafe {
51 errcheck!(GEOSBufferParams_setJoinStyle_r(
52 ctx.as_raw(),
53 self.as_raw_mut_override(),
54 style.into(),
55 ))?;
56 Ok(())
57 })
58 }
59
60 pub fn set_mitre_limit(&mut self, limit: f64) -> GResult<()> {
71 with_context(|ctx| unsafe {
72 errcheck!(GEOSBufferParams_setMitreLimit_r(
73 ctx.as_raw(),
74 self.as_raw_mut_override(),
75 limit
76 ))?;
77 Ok(())
78 })
79 }
80
81 pub fn set_quadrant_segments(&mut self, quadsegs: i32) -> GResult<()> {
102 with_context(|ctx| unsafe {
103 errcheck!(GEOSBufferParams_setQuadrantSegments_r(
104 ctx.as_raw(),
105 self.as_raw_mut_override(),
106 quadsegs as _,
107 ))?;
108 Ok(())
109 })
110 }
111
112 pub fn set_single_sided(&mut self, is_single_sided: bool) -> GResult<()> {
125 with_context(|ctx| unsafe {
126 errcheck!(GEOSBufferParams_setSingleSided_r(
127 ctx.as_raw(),
128 self.as_raw_mut_override(),
129 is_single_sided.into(),
130 ))?;
131 Ok(())
132 })
133 }
134}
135
136unsafe impl Send for BufferParams {}
137unsafe impl Sync for BufferParams {}
138
139impl Drop for BufferParams {
140 fn drop(&mut self) {
141 with_context(|ctx| unsafe { GEOSBufferParams_destroy_r(ctx.as_raw(), self.as_raw_mut()) });
142 }
143}
144
145as_raw_mut_impl!(BufferParams, GEOSBufferParams);
146
147impl BufferParamsBuilder {
148 pub const fn end_cap_style(mut self, style: CapStyle) -> Self {
149 self.end_cap_style = Some(style);
150 self
151 }
152 pub const fn join_style(mut self, style: JoinStyle) -> Self {
153 self.join_style = Some(style);
154 self
155 }
156 pub const fn mitre_limit(mut self, limit: f64) -> Self {
157 self.mitre_limit = Some(limit);
158 self
159 }
160 pub const fn quadrant_segments(mut self, quadsegs: i32) -> Self {
161 self.quadrant_segments = Some(quadsegs);
162 self
163 }
164 pub const fn single_sided(mut self, is_single_sided: bool) -> Self {
165 self.single_sided = Some(is_single_sided);
166 self
167 }
168 pub fn build(self) -> GResult<BufferParams> {
169 let mut params = BufferParams::new()?;
170 if let Some(style) = self.end_cap_style {
171 params.set_end_cap_style(style)?;
172 }
173 if let Some(style) = self.join_style {
174 params.set_join_style(style)?;
175 }
176 if let Some(limit) = self.mitre_limit {
177 params.set_mitre_limit(limit)?;
178 }
179 if let Some(quad_segs) = self.quadrant_segments {
180 params.set_quadrant_segments(quad_segs)?;
181 }
182 if let Some(is_single_sided) = self.single_sided {
183 params.set_single_sided(is_single_sided)?;
184 }
185 Ok(params)
186 }
187}