1use crate::error::LaserError;
2use crate::laser::Laser;
3use std::collections::BTreeMap;
4
5pub use iggy::prelude::{HeaderKey, HeaderValue};
6
7pub use iggy::prelude::{
12 BackgroundConfig, BalancedSharding, DirectConfig, IggyConsumer, IggyConsumerBuilder,
13 IggyMessage, IggyProducer, IggyProducerBuilder, OrderedSharding,
14 SendMessagesConfirmationResponse, SendMessagesResponse, Sharding,
15};
16
17pub use laser_wire::codecs::{Cbor, Codec, Decoder, Json, Msgpack};
18pub use laser_wire::content::ContentType;
19pub use laser_wire::headers::{
20 CONTENT_TYPE, IDX_PREFIX, INLINE_PAYLOAD, LOGICAL_SCHEMA_FINGERPRINT, PROJECTION_REF, SCHEMA_ID,
21};
22pub use laser_wire::limits::MAX_INDEX_ENTRIES_PER_RECORD;
23
24mod consumer_group;
25pub(crate) mod producer_statistics;
26mod publish;
27mod record;
28pub(crate) mod transport;
29
30pub(crate) use consumer_group::GroupTarget;
31pub use consumer_group::{ConsumerGroup, ConsumerGroupInfo, CreateConsumerGroup, GroupFilter};
32pub use publish::{BatchPublishRequest, PublishRequest};
33pub use record::{Record, RecordBuilder};
34pub use transport::{
35 CommitPolicy, Consumer, ConsumerBuilder, ConsumerMessage, ConsumerStart, Headers, Producer,
36 ProducerBuilder, ProducerMessage, Routing, StoredOffset,
37};
38
39impl Laser {
40 pub fn stream(&self, name: impl Into<String>) -> Stream {
45 Stream {
46 laser: self.clone(),
47 name: name.into(),
48 }
49 }
50
51 pub fn topic(&self, name: impl Into<String>) -> Topic {
58 Topic {
59 laser: self.clone(),
60 stream: self.default_stream().map(str::to_owned),
61 name: name.into(),
62 }
63 }
64}
65
66#[derive(Clone)]
69pub struct Stream {
70 laser: Laser,
71 name: String,
72}
73
74impl Stream {
75 pub fn topic(&self, name: impl Into<String>) -> Topic {
77 Topic {
78 laser: self.laser.clone(),
79 stream: Some(self.name.clone()),
80 name: name.into(),
81 }
82 }
83
84 pub async fn ensure(&self) -> Result<(), LaserError> {
86 crate::laser::ensure_stream(&self.laser.client(), &self.name).await
87 }
88
89 pub async fn delete(&self) -> Result<bool, LaserError> {
91 crate::laser::delete_stream(&self.laser, &self.name).await
92 }
93
94 pub fn name(&self) -> &str {
96 &self.name
97 }
98}
99
100#[derive(Clone)]
105pub struct Topic {
106 laser: Laser,
107 stream: Option<String>,
108 name: String,
109}
110
111impl Topic {
112 pub fn publish(&self) -> PublishRequest<'_> {
117 match &self.stream {
118 Some(stream) => self.laser.publish_on(stream, &self.name),
119 None => self.laser.publish(&self.name),
120 }
121 }
122
123 pub fn publish_batch(&self) -> BatchPublishRequest<'_> {
126 match &self.stream {
127 Some(stream) => self.laser.publish_batch_on(stream, &self.name),
128 None => self.laser.publish_batch(&self.name),
129 }
130 }
131
132 pub async fn send(
136 &self,
137 payload: impl Into<Vec<u8>>,
138 headers: BTreeMap<HeaderKey, HeaderValue>,
139 partition_key: Option<&str>,
140 ) -> Result<SendMessagesResponse, LaserError> {
141 let stream = self.stream()?.to_owned();
142 self.laser
143 .send_with_headers_on(&stream, &self.name, payload.into(), headers, partition_key)
144 .await
145 }
146
147 pub async fn batch(
150 &self,
151 messages: Vec<IggyMessage>,
152 partition_key: Option<&str>,
153 ) -> Result<SendMessagesResponse, LaserError> {
154 let stream = self.stream()?.to_owned();
155 self.laser
156 .send_batch_on(&stream, &self.name, messages, partition_key)
157 .await
158 }
159
160 #[cfg(feature = "agent")]
165 pub fn batching(&self) -> Result<crate::batching::BatchingProducerBuilder, LaserError> {
166 let stream = self.stream()?.to_owned();
167 Ok(crate::batching::BatchingProducerBuilder::new(
168 self.laser.clone(),
169 stream,
170 self.name.clone(),
171 ))
172 }
173
174 pub fn replay(&self) -> Result<crate::cursor::Cursor, LaserError> {
180 match &self.stream {
181 Some(stream) => self.laser.reader_on(stream, &self.name),
182 None => Err(LaserError::NoStream),
183 }
184 }
185
186 pub async fn ensure(&self, partitions: u32) -> Result<(), LaserError> {
189 let stream = self.stream()?.to_owned();
190 self.laser
191 .ensure_topic_on(&stream, &self.name, partitions)
192 .await
193 }
194
195 pub async fn ensure_consumer_group(&self, name: &str) -> Result<(), LaserError> {
200 self.consumer_group(name).create().build().await.map(|_| ())
201 }
202
203 pub fn iggy_producer(&self) -> Result<IggyProducerBuilder, LaserError> {
207 self.laser.iggy_producer(self.stream()?, &self.name)
208 }
209
210 pub fn iggy_consumer(
213 &self,
214 name: &str,
215 partition: u32,
216 ) -> Result<IggyConsumerBuilder, LaserError> {
217 self.laser
218 .iggy_consumer(name, self.stream()?, &self.name, partition)
219 }
220
221 pub fn iggy_consumer_group(&self, group: &str) -> Result<IggyConsumerBuilder, LaserError> {
224 self.laser
225 .iggy_consumer_group(group, self.stream()?, &self.name)
226 }
227
228 pub fn producer(&self) -> ProducerBuilder {
232 ProducerBuilder::new(self.clone())
233 }
234
235 pub fn consumer(&self, name: impl Into<String>, partition: u32) -> ConsumerBuilder {
238 ConsumerBuilder::partition(self.clone(), name, partition)
239 }
240
241 pub fn consumer_group(&self, group: impl Into<String>) -> ConsumerGroup {
245 ConsumerGroup::new(self.clone(), GroupTarget::Name(group.into()))
246 }
247
248 pub fn consumer_group_id(&self, id: u64) -> ConsumerGroup {
251 ConsumerGroup::new(self.clone(), GroupTarget::Id(id))
252 }
253
254 pub fn name(&self) -> &str {
256 &self.name
257 }
258
259 pub(crate) fn laser(&self) -> &Laser {
260 &self.laser
261 }
262
263 pub(crate) fn stream(&self) -> Result<&str, LaserError> {
264 self.stream.as_deref().ok_or(LaserError::NoStream)
265 }
266}