1use std::borrow::Cow;
2use std::pin::Pin;
3
4use crate::Rep;
5
6#[cxx::bridge]
7mod ffi {
8 #[namespace = "absl"]
9 unsafe extern "C++" {
10 include!(<absl/time/time.h>);
11
12 type Duration = super::Duration;
13 fn Nanoseconds(n: i64) -> Duration;
14 fn ToInt64Nanoseconds(duration: Duration) -> i64;
15
16 type Time = super::Timestamp;
17 fn ToUnixNanos(time: Time) -> i64;
18 fn FromUnixNanos(nanos: i64) -> Time;
19
20 include!(<absl/status/status.h>);
21 type StatusCode = super::StatusCode;
22
23 type Status = super::Status;
24 #[rust_name = "is_ok"]
25 fn ok(self: &Status) -> bool;
26 fn code(self: &Status) -> StatusCode;
27 fn message<'a>(self: &'a Status) -> string_view<'a>;
28
29 fn OkStatus() -> Status;
30 fn IsAborted(status: &Status) -> bool;
31 fn IsAlreadyExists(status: &Status) -> bool;
32 fn IsCancelled(status: &Status) -> bool;
33 fn IsDataLoss(status: &Status) -> bool;
34 fn IsDeadlineExceeded(status: &Status) -> bool;
35 fn IsFailedPrecondition(status: &Status) -> bool;
36 fn IsInternal(status: &Status) -> bool;
37 fn IsInvalidArgument(status: &Status) -> bool;
38 fn IsNotFound(status: &Status) -> bool;
39 fn IsOutOfRange(status: &Status) -> bool;
40 fn IsPermissionDenied(status: &Status) -> bool;
41 fn IsResourceExhausted(status: &Status) -> bool;
42 fn IsUnauthenticated(status: &Status) -> bool;
43 fn IsUnavailable(status: &Status) -> bool;
44 fn IsUnimplemented(status: &Status) -> bool;
45 fn IsUnknown(status: &Status) -> bool;
46
47 fn AbortedError(msg: string_view) -> Status;
48 fn AlreadyExistsError(msg: string_view) -> Status;
49 fn CancelledError(msg: string_view) -> Status;
50 fn DataLossError(msg: string_view) -> Status;
51 fn DeadlineExceededError(msg: string_view) -> Status;
52 fn FailedPreconditionError(msg: string_view) -> Status;
53 fn InternalError(msg: string_view) -> Status;
54 fn InvalidArgumentError(msg: string_view) -> Status;
55 fn NotFoundError(msg: string_view) -> Status;
56 fn OutOfRangeError(msg: string_view) -> Status;
57 fn PermissionDeniedError(msg: string_view) -> Status;
58 fn ResourceExhaustedError(msg: string_view) -> Status;
59 fn UnauthenticatedError(msg: string_view) -> Status;
60 fn UnavailableError(msg: string_view) -> Status;
61 fn UnimplementedError(msg: string_view) -> Status;
62 fn UnknownError(msg: string_view) -> Status;
63
64 include!(<absl/strings/string_view.h>);
65 #[allow(unused, non_camel_case_types)]
66 type string_view<'a> = super::StringView<'a>;
67 #[rust_name = "len"]
68 fn size(self: &string_view) -> usize;
69 fn data(self: &string_view) -> *const c_char;
70 }
71
72 #[namespace = "absl"]
73 unsafe extern "C++" {
74 include!(<absl/log/log_entry.h>);
75
76 type LogSeverity = super::log::LogSeverity;
77 type LogSeverityAtLeast = super::log::LogSeverityAtLeast;
78
79 type LogEntry;
80 fn log_severity(self: &LogEntry) -> LogSeverity;
82 fn text_message<'a>(self: &'a LogEntry) -> string_view<'a>;
83 fn source_filename<'a>(self: &'a LogEntry) -> string_view<'a>;
84 fn source_line(self: &LogEntry) -> i32;
86
87 include!(<absl/log/globals.h>);
88 #[rust_name = "set_stderr_threshold"]
89 fn SetStderrThreshold(severity: LogSeverityAtLeast);
90 }
91
92 #[namespace = "rust::cel_cxx"]
93 unsafe extern "C++" {
94 include!(<cel-cxx-ffi/include/absl.h>);
95
96 fn Duration_new(seconds: i64, nanos: u32) -> Duration;
97 fn Duration_seconds(duration: Duration) -> i64;
98 fn Duration_nanos(duration: Duration) -> u32;
99
100 fn Timestamp_new(seconds: i64, nanos: u32) -> Time;
101 fn Timestamp_seconds(timestamp: Time) -> i64;
102 fn Timestamp_nanos(timestamp: Time) -> u32;
103
104 fn StringView_new<'a>(bytes: &'a [u8]) -> string_view<'a>;
105
106 fn StatusCode_to_string(code: StatusCode) -> String;
107
108 fn Status_new(code: StatusCode, msg: &str) -> Status;
109 fn Status_clone(status: &Status) -> Status;
110 fn Status_drop(status: &mut Status);
111 fn Status_to_string(status: &Status) -> String;
112
113 #[rust_name = "initialize_log"]
114 fn InitializeLog();
115
116 #[rust_name = "set_log_callback"]
117 fn SetLogCallback();
118 }
119
120 #[namespace = "rust::cel_cxx"]
121 extern "Rust" {
122 #[cxx_name = "LogCallback"]
123 fn log_callback(entry: &LogEntry);
124 }
125}
126
127use log::log_callback;
128pub mod log {
129 use super::ffi;
130 use std::sync::Once;
131
132 #[allow(dead_code)]
133 #[repr(i32)]
134 #[derive(Copy, Clone)]
135 pub(super) enum LogSeverity {
136 Info = 0,
137 Warning = 1,
138 Error = 2,
139 Fatal = 3,
140 }
141 unsafe impl cxx::ExternType for LogSeverity {
142 type Id = cxx::type_id!("absl::LogSeverity");
143 type Kind = cxx::kind::Trivial;
144 }
145
146 #[allow(dead_code)]
147 #[repr(i32)]
148 #[derive(Copy, Clone)]
149 pub(super) enum LogSeverityAtLeast {
150 Info = 0,
151 Warning = 1,
152 Error = 2,
153 Fatal = 3,
154 Infinity = 1000,
155 }
156 unsafe impl cxx::ExternType for LogSeverityAtLeast {
157 type Id = cxx::type_id!("absl::LogSeverityAtLeast");
158 type Kind = cxx::kind::Trivial;
159 }
160
161 static ONCE: Once = Once::new();
162
163 pub fn init() {
166 ONCE.call_once(|| {
167 ffi::initialize_log();
168
169 ffi::set_log_callback();
170
171 ffi::set_stderr_threshold(LogSeverityAtLeast::Infinity);
172 });
173 }
174
175 pub(super) fn log_callback(entry: &ffi::LogEntry) {
177 let level = match entry.log_severity() {
179 LogSeverity::Info => log::Level::Info,
180 LogSeverity::Warning => log::Level::Warn,
181 LogSeverity::Error => log::Level::Error,
182 LogSeverity::Fatal => log::Level::Error,
183 };
184
185 let message = entry.text_message().to_string_lossy();
187 let file = entry.source_filename().to_string_lossy();
188 let line = entry.source_line();
189
190 log::logger().log(
192 &log::Record::builder()
193 .args(format_args!("{message}"))
194 .level(level)
195 .file(Some(file.as_ref()))
196 .line(if line > 0 { Some(line as u32) } else { None })
197 .build()
198 );
199 }
200}
201
202#[repr(transparent)]
203#[derive(Copy, Clone)]
204pub struct Duration(Rep<'static, u32, 3>);
205
206unsafe impl cxx::ExternType for Duration {
207 type Id = cxx::type_id!("absl::Duration");
208 type Kind = cxx::kind::Trivial;
209}
210
211impl Duration {
212 pub fn new(seconds: i64, nanos: u32) -> Self {
213 ffi::Duration_new(seconds, nanos)
214 }
215
216 pub fn from_nanos(nanos: i64) -> Self {
217 ffi::Nanoseconds(nanos)
218 }
219
220 pub fn to_nanos(&self) -> i64 {
221 ffi::ToInt64Nanoseconds(*self)
222 }
223
224 pub fn seconds(&self) -> i64 {
225 ffi::Duration_seconds(*self)
226 }
227
228 pub fn nanos(&self) -> u32 {
229 ffi::Duration_nanos(*self)
230 }
231}
232
233impl From<chrono::Duration> for Duration {
234 fn from(value: chrono::Duration) -> Self {
235 Self::new(value.num_seconds(), value.subsec_nanos() as u32)
236 }
237}
238
239impl From<Duration> for chrono::Duration {
240 fn from(value: Duration) -> Self {
241 Self::new(value.seconds(), value.nanos()).unwrap_or_default()
242 }
243}
244
245#[repr(transparent)]
246#[derive(Copy, Clone)]
247pub struct Timestamp(Rep<'static, u32, 3>);
248
249unsafe impl cxx::ExternType for Timestamp {
250 type Id = cxx::type_id!("absl::Time");
251 type Kind = cxx::kind::Trivial;
252}
253
254impl Timestamp {
255 pub fn new(seconds: i64, nanos: u32) -> Self {
256 ffi::Timestamp_new(seconds, nanos)
257 }
258
259 pub fn from_unix_nanos(nanos: i64) -> Self {
260 ffi::FromUnixNanos(nanos)
261 }
262
263 pub fn unix_nanos(&self) -> i64 {
264 ffi::ToUnixNanos(*self)
265 }
266
267 pub fn seconds(&self) -> i64 {
268 ffi::Timestamp_seconds(*self)
269 }
270
271 pub fn nanos(&self) -> u32 {
272 ffi::Timestamp_nanos(*self)
273 }
274}
275
276impl From<chrono::DateTime<chrono::Utc>> for Timestamp {
277 fn from(value: chrono::DateTime<chrono::Utc>) -> Self {
278 Self::new(value.timestamp(), value.timestamp_subsec_nanos())
279 }
280}
281
282impl From<Timestamp> for chrono::DateTime<chrono::Utc> {
283 fn from(value: Timestamp) -> Self {
284 Self::from_timestamp(value.seconds(), value.nanos()).unwrap_or_default()
285 }
286}
287
288#[repr(i32)]
290#[derive(Copy, Clone)]
291pub enum StatusCode {
292 Ok = 0,
293 Cancelled = 1,
294 Unknown = 2,
295 InvalidArgument = 3,
296 DeadlineExceeded = 4,
297 NotFound = 5,
298 AlreadyExists = 6,
299 PermissionDenied = 7,
300 ResourceExhausted = 8,
301 FailedPrecondition = 9,
302 Aborted = 10,
303 OutOfRange = 11,
304 Unimplemented = 12,
305 Internal = 13,
306 Unavailable = 14,
307 DataLoss = 15,
308 Unauthenticated = 16,
309}
310
311unsafe impl cxx::ExternType for StatusCode {
312 type Id = cxx::type_id!("absl::StatusCode");
313 type Kind = cxx::kind::Trivial;
314}
315
316impl std::fmt::Display for StatusCode {
317 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
318 let string = ffi::StatusCode_to_string(*self);
319 write!(f, "{string}")
320 }
321}
322
323#[repr(transparent)]
325pub struct Status(Rep<'static, usize, 1>);
326
327unsafe impl cxx::ExternType for Status {
328 type Id = cxx::type_id!("absl::Status");
329 type Kind = cxx::kind::Trivial;
330}
331
332impl Clone for Status {
333 fn clone(&self) -> Self {
334 ffi::Status_clone(self)
335 }
336}
337
338impl Drop for Status {
339 fn drop(&mut self) {
340 ffi::Status_drop(self)
341 }
342}
343
344impl Default for Status {
345 fn default() -> Self {
346 ffi::OkStatus()
347 }
348}
349
350impl std::fmt::Display for Status {
351 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
352 let string = ffi::Status_to_string(self);
353 write!(f, "{string}")
354 }
355}
356
357impl std::fmt::Debug for Status {
358 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
359 let string = ffi::Status_to_string(self);
360 write!(f, "{string}")
361 }
362}
363
364impl std::error::Error for Status {}
365
366impl Status {
367 pub fn new(code: StatusCode, message: &str) -> Self {
368 ffi::Status_new(code, message)
369 }
370
371 pub fn ok() -> Self {
372 ffi::OkStatus()
373 }
374
375 pub fn is_aborted(&self) -> bool {
376 ffi::IsAborted(self)
377 }
378
379 pub fn is_already_exists(&self) -> bool {
380 ffi::IsAlreadyExists(self)
381 }
382
383 pub fn is_cancelled(&self) -> bool {
384 ffi::IsCancelled(self)
385 }
386
387 pub fn is_data_loss(&self) -> bool {
388 ffi::IsDataLoss(self)
389 }
390
391 pub fn is_deadline_exceeded(&self) -> bool {
392 ffi::IsDeadlineExceeded(self)
393 }
394
395 pub fn is_failed_precondition(&self) -> bool {
396 ffi::IsFailedPrecondition(self)
397 }
398
399 pub fn is_internal(&self) -> bool {
400 ffi::IsInternal(self)
401 }
402
403 pub fn is_invalid_argument(&self) -> bool {
404 ffi::IsInvalidArgument(self)
405 }
406
407 pub fn is_not_found(&self) -> bool {
408 ffi::IsNotFound(self)
409 }
410
411 pub fn is_out_of_range(&self) -> bool {
412 ffi::IsOutOfRange(self)
413 }
414
415 pub fn is_permission_denied(&self) -> bool {
416 ffi::IsPermissionDenied(self)
417 }
418
419 pub fn is_resource_exhausted(&self) -> bool {
420 ffi::IsResourceExhausted(self)
421 }
422
423 pub fn is_unauthenticated(&self) -> bool {
424 ffi::IsUnauthenticated(self)
425 }
426
427 pub fn is_unavailable(&self) -> bool {
428 ffi::IsUnavailable(self)
429 }
430
431 pub fn is_unimplemented(&self) -> bool {
432 ffi::IsUnimplemented(self)
433 }
434
435 pub fn is_unknown(&self) -> bool {
436 ffi::IsUnknown(self)
437 }
438
439 pub fn aborted(msg: &str) -> Self {
440 ffi::AbortedError(StringView::new_str(msg))
441 }
442
443 pub fn already_exists(msg: &str) -> Self {
444 ffi::AlreadyExistsError(StringView::new_str(msg))
445 }
446
447 pub fn cancelled(msg: &str) -> Self {
448 ffi::CancelledError(StringView::new_str(msg))
449 }
450
451 pub fn data_loss(msg: &str) -> Self {
452 ffi::DataLossError(StringView::new_str(msg))
453 }
454
455 pub fn deadline_exceeded(msg: &str) -> Self {
456 ffi::DeadlineExceededError(StringView::new_str(msg))
457 }
458
459 pub fn failed_precondition(msg: &str) -> Self {
460 ffi::FailedPreconditionError(StringView::new_str(msg))
461 }
462
463 pub fn internal(msg: &str) -> Self {
464 ffi::InternalError(StringView::new_str(msg))
465 }
466
467 pub fn invalid_argument(msg: &str) -> Self {
468 ffi::InvalidArgumentError(StringView::new_str(msg))
469 }
470
471 pub fn not_found(msg: &str) -> Self {
472 ffi::NotFoundError(StringView::new_str(msg))
473 }
474
475 pub fn out_of_range(msg: &str) -> Self {
476 ffi::OutOfRangeError(StringView::new_str(msg))
477 }
478
479 pub fn permission_denied(msg: &str) -> Self {
480 ffi::PermissionDeniedError(StringView::new_str(msg))
481 }
482
483 pub fn resource_exhausted(msg: &str) -> Self {
484 ffi::ResourceExhaustedError(StringView::new_str(msg))
485 }
486
487 pub fn unauthenticated(msg: &str) -> Self {
488 ffi::UnauthenticatedError(StringView::new_str(msg))
489 }
490
491 pub fn unavailable(msg: &str) -> Self {
492 ffi::UnavailableError(StringView::new_str(msg))
493 }
494
495 pub fn unimplemented(msg: &str) -> Self {
496 ffi::UnimplementedError(StringView::new_str(msg))
497 }
498
499 pub fn unknown(msg: &str) -> Self {
500 ffi::UnknownError(StringView::new_str(msg))
501 }
502}
503
504#[repr(C)]
506pub struct Span<'a, T: 'a + SpanElement> {
507 ptr: *const T,
508 len: usize,
509 _marker: std::marker::PhantomData<&'a T>,
510}
511
512impl<'a, T: 'a + SpanElement> Copy for Span<'a, T> {}
513impl<'a, T: 'a + SpanElement> Clone for Span<'a, T> {
514 fn clone(&self) -> Self {
515 *self
516 }
517}
518
519unsafe impl<'a, T: 'a + SpanElement> cxx::ExternType for Span<'a, T> {
520 type Id = T::TypeId;
521 type Kind = cxx::kind::Trivial;
522}
523
524impl<'a, T: 'a + SpanElement> Span<'a, T> {
525 pub fn len(&self) -> usize {
526 self.len
527 }
528
529 pub fn is_empty(&self) -> bool {
530 self.len == 0
531 }
532
533 pub fn get(&self, index: usize) -> Option<&'a T> {
534 if index < self.len() {
535 let offset = index * T::size_of();
536 unsafe { self.ptr.byte_add(offset).as_ref() }
537 } else {
538 None
539 }
540 }
541
542 pub fn iter(&self) -> SpanIter<'a, T> {
543 SpanIter {
544 span: *self,
545 index: 0,
546 }
547 }
548}
549
550impl<'a, T: 'a + SpanElement + cxx::vector::VectorElement> Span<'a, T> {
551 pub fn from_vector(vector: &'a cxx::CxxVector<T>) -> Self {
552 Self {
553 ptr: unsafe { vector.get_unchecked(0) as *const T },
554 len: vector.len(),
555 _marker: std::marker::PhantomData,
556 }
557 }
558}
559
560impl<'a, T: 'a + SpanElement + cxx::ExternType<Kind = cxx::kind::Trivial>> Span<'a, T> {
561 pub fn from_slice(slice: &'a [T]) -> Self {
562 Self {
563 ptr: slice.as_ptr(),
564 len: slice.len(),
565 _marker: std::marker::PhantomData,
566 }
567 }
568
569 pub fn as_slice(&self) -> &'a [T] {
570 unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
571 }
572}
573
574pub struct SpanIter<'a, T: 'a + SpanElement> {
575 span: Span<'a, T>,
576 index: usize,
577}
578
579impl<'a, T: 'a + SpanElement> std::iter::Iterator for SpanIter<'a, T> {
580 type Item = &'a T;
581
582 fn next(&mut self) -> Option<Self::Item> {
583 if let Some(item) = self.span.get(self.index) {
584 self.index += 1;
585 Some(item)
586 } else {
587 None
588 }
589 }
590
591 fn size_hint(&self) -> (usize, Option<usize>) {
592 (
593 self.span.len() - self.index,
594 Some(self.span.len() - self.index),
595 )
596 }
597}
598
599impl<'a, T: 'a + SpanElement> std::iter::FusedIterator for SpanIter<'a, T> {}
600impl<'a, T: 'a + SpanElement> std::iter::ExactSizeIterator for SpanIter<'a, T> {}
601impl<'a, T: 'a + SpanElement> std::iter::IntoIterator for Span<'a, T> {
602 type Item = &'a T;
603 type IntoIter = SpanIter<'a, T>;
604
605 fn into_iter(self) -> Self::IntoIter {
606 SpanIter {
607 span: self,
608 index: 0,
609 }
610 }
611}
612
613impl<'a, T: 'a + SpanElement + std::fmt::Debug> std::fmt::Debug for Span<'a, T> {
614 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
615 f.debug_list().entries(self.iter()).finish()
616 }
617}
618
619pub trait SpanElement: crate::SizedExternType {
620 type TypeId;
621}
622
623pub struct MutSpan<'a, T: 'a + MutSpanElement> {
625 ptr: *mut T,
626 len: usize,
627 _marker: std::marker::PhantomData<&'a mut T>,
628}
629
630impl<'a, T: 'a + MutSpanElement> Copy for MutSpan<'a, T> {}
631impl<'a, T: 'a + MutSpanElement> Clone for MutSpan<'a, T> {
632 fn clone(&self) -> Self {
633 *self
634 }
635}
636
637unsafe impl<'a, T: 'a + MutSpanElement> cxx::ExternType for MutSpan<'a, T> {
638 type Id = T::TypeId;
639 type Kind = cxx::kind::Trivial;
640}
641
642impl<'a, T: 'a + MutSpanElement> MutSpan<'a, T> {
643 pub fn len(&self) -> usize {
644 self.len
645 }
646
647 pub fn is_empty(&self) -> bool {
648 self.len == 0
649 }
650
651 pub fn get(&self, index: usize) -> Option<Pin<&'a mut T>> {
652 if index < self.len() {
653 unsafe {
654 self.ptr.byte_add(index * T::size_of())
655 .as_mut()
656 .map(|ptr| Pin::new_unchecked(ptr))
657 }
658 } else {
659 None
660 }
661 }
662
663 pub fn iter(&self) -> MutSpanIter<'a, T> {
664 MutSpanIter {
665 span: *self,
666 index: 0,
667 }
668 }
669}
670
671impl<'a, T: 'a + MutSpanElement + cxx::vector::VectorElement> MutSpan<'a, T> {
672 pub fn from_vector(mut vector: Pin<&'a mut cxx::CxxVector<T>>) -> Self {
673 Self {
674 ptr: unsafe { vector.as_mut().index_unchecked_mut(0).get_unchecked_mut() as *mut T },
675 len: vector.len(),
676 _marker: std::marker::PhantomData,
677 }
678 }
679}
680
681impl<'a, T: 'a + MutSpanElement + cxx::ExternType<Kind = cxx::kind::Trivial>> MutSpan<'a, T> {
682 pub fn from_slice(slice: &'a mut [T]) -> Self {
683 Self {
684 ptr: slice.as_mut_ptr(),
685 len: slice.len(),
686 _marker: std::marker::PhantomData,
687 }
688 }
689
690 pub fn as_slice(&self) -> &'a mut [T] {
691 unsafe { std::slice::from_raw_parts_mut(self.ptr, self.len) }
692 }
693}
694
695pub struct MutSpanIter<'a, T: 'a + MutSpanElement> {
696 span: MutSpan<'a, T>,
697 index: usize,
698}
699
700impl<'a, T: 'a + MutSpanElement> std::iter::Iterator for MutSpanIter<'a, T> {
701 type Item = Pin<&'a mut T>;
702
703 fn next(&mut self) -> Option<Self::Item> {
704 if let Some(item) = self.span.get(self.index) {
705 self.index += 1;
706 Some(item)
707 } else {
708 None
709 }
710 }
711
712 fn size_hint(&self) -> (usize, Option<usize>) {
713 (
714 self.span.len() - self.index,
715 Some(self.span.len() - self.index),
716 )
717 }
718}
719impl<'a, T: 'a + MutSpanElement> std::iter::FusedIterator for MutSpanIter<'a, T> {}
720impl<'a, T: 'a + MutSpanElement> std::iter::ExactSizeIterator for MutSpanIter<'a, T> {}
721impl<'a, T: 'a + MutSpanElement> std::iter::IntoIterator for &MutSpan<'a, T> {
722 type Item = Pin<&'a mut T>;
723 type IntoIter = MutSpanIter<'a, T>;
724 fn into_iter(self) -> Self::IntoIter {
725 MutSpanIter { span: *self, index: 0 }
726 }
727}
728
729impl<'a, T: 'a + MutSpanElement + std::fmt::Debug> std::fmt::Debug for MutSpan<'a, T> {
730 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
731 f.debug_list().entries(self.iter()).finish()
732 }
733}
734
735pub trait MutSpanElement: crate::SizedExternType {
736 type TypeId;
737}
738
739#[repr(C)]
741#[derive(Copy, Clone)]
742pub struct StringView<'a>(Rep<'a, usize, 2>);
743
744unsafe impl<'a> cxx::ExternType for StringView<'a> {
745 type Id = cxx::type_id!("absl::string_view");
746 type Kind = cxx::kind::Trivial;
747}
748
749impl<'a> crate::SizedExternType for StringView<'a> {}
750
751impl<'a> SpanElement for StringView<'a> {
752 type TypeId = cxx::type_id!("rust::cel_cxx::Span_StringView");
753}
754
755impl<'a> StringView<'a> {
756 pub fn new(bytes: &'a [u8]) -> Self {
757 ffi::StringView_new(bytes)
758 }
759
760 pub fn new_str(s: &'a str) -> Self {
761 Self::new(s.as_bytes())
762 }
763
764 pub fn is_empty(&self) -> bool {
765 self.len() == 0
766 }
767
768 pub fn as_bytes(&self) -> &'a [u8] {
769 unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len()) }
770 }
771
772 pub fn to_str(&self) -> Result<&'a str, std::str::Utf8Error> {
773 std::str::from_utf8(self.as_bytes())
774 }
775
776 pub fn to_string_lossy(&self) -> Cow<'a, str> {
777 String::from_utf8_lossy(self.as_bytes())
778 }
779
780 pub fn as_ptr(&self) -> *const u8 {
781 self.data() as *const u8
782 }
783}
784
785impl<'a> From<&'a str> for StringView<'a> {
786 fn from(value: &'a str) -> Self {
787 Self::new_str(value)
788 }
789}
790
791impl<'a> From<&'a String> for StringView<'a> {
792 fn from(value: &'a String) -> Self {
793 Self::new_str(value.as_str())
794 }
795}
796
797impl<'a> From<&'a [u8]> for StringView<'a> {
798 fn from(value: &'a [u8]) -> Self {
799 Self::new(value)
800 }
801}
802
803impl<'a> From<&'a Vec<u8>> for StringView<'a> {
804 fn from(value: &'a Vec<u8>) -> Self {
805 Self::new(value.as_slice())
806 }
807}