@@ -3,7 +3,7 @@ import gleam/bool
33import gleam/dict . { type Dict }
44import gleam/erlang/process . { type Subject }
55import gleam/list
6- import gleam/option . { type Option , None , Some }
6+ import gleam/option . { None , Some }
77import gleam/otp/actor
88import gleam/result
99import gleam/set . { type Set }
@@ -13,6 +13,9 @@ const mds_port = 5353
1313
1414const all_services_type = "_services._dns-sd._udp.local"
1515
16+ pub type IpAddress =
17+ toss . IpAddress
18+
1619/// Describes a service fully discovered via DNS-SD.
1720pub type ServiceDescription {
1821 ServiceDescription (
@@ -35,10 +38,8 @@ pub type ServiceDescription {
3538 port : Int ,
3639 /// Any TXT records that the service advertises (can be empty).
3740 txt_values : List ( String ) ,
38- /// The IPv4 address, if advertised.
39- ipv4 : Option ( # ( Int , Int , Int , Int ) ) ,
40- /// The IPv6 address, if advertised.
41- ipv6 : Option ( # ( Int , Int , Int , Int , Int , Int , Int , Int ) ) ,
41+ /// The resolved IP address
42+ ip : IpAddress ,
4243 )
4344}
4445
@@ -288,24 +289,26 @@ fn description_from_records(
288289 service_type : String ,
289290 instance_name : String ,
290291) -> Result ( ServiceDescription , Nil ) {
291- use # ( priority , weight , port , target_name ) <- result . try (
292- list . find_map ( records , fn ( record ) {
293- case record {
294- dns . SrvRecord ( priority : , weight : , port : , target_name : , .. ) ->
295- Ok ( # ( priority , weight , port , target_name ) )
296- _ -> Error ( Nil )
297- }
298- } ) ,
299- )
292+ let try_find = fn ( with : fn ( ResourceRecord ) -> Result ( a, Nil ) , apply ) {
293+ result . try ( list . find_map ( records , with ) , apply )
294+ }
300295
301- let # ( ipv4 , ipv6 ) =
302- list . fold ( records , # ( None , None ) , fn ( ips , record ) {
303- case record {
304- dns . ARecord ( ip : , .. ) -> # ( Some ( ip ) , ips . 1 )
305- dns . AaaaRecord ( ip : , .. ) -> # ( ips . 0 , Some ( ip ) )
306- _ -> ips
307- }
308- } )
296+ use # ( priority , weight , port , target_name ) <- try_find ( fn ( record ) {
297+ case record {
298+ dns . SrvRecord ( priority : , weight : , port : , target_name : , .. ) ->
299+ Ok ( # ( priority , weight , port , target_name ) )
300+ _ -> Error ( Nil )
301+ }
302+ } )
303+
304+ use ip <- try_find ( fn ( record ) {
305+ case record {
306+ dns . ARecord ( ip : , .. ) -> Ok ( toss . Ipv4Address ( ip . 0 , ip . 1 , ip . 2 , ip . 3 ) )
307+ dns . AaaaRecord ( ip : , .. ) ->
308+ Ok ( toss . Ipv6Address ( ip . 0 , ip . 1 , ip . 2 , ip . 3 , ip . 4 , ip . 5 , ip . 6 , ip . 7 ) )
309+ _ -> Error ( Nil )
310+ }
311+ } )
309312
310313 let txt_values =
311314 list . flat_map ( records , fn ( record ) {
@@ -315,19 +318,14 @@ fn description_from_records(
315318 }
316319 } )
317320
318- case option . is_some ( ipv4 ) || option . is_some ( ipv6 ) {
319- True ->
320- Ok ( ServiceDescription (
321- service_type : ,
322- instance_name : ,
323- target_name : ,
324- priority : ,
325- weight : ,
326- port : ,
327- txt_values : ,
328- ipv4 : ,
329- ipv6 : ,
330- ) )
331- False -> Error ( Nil )
332- }
321+ Ok ( ServiceDescription (
322+ service_type : ,
323+ instance_name : ,
324+ target_name : ,
325+ priority : ,
326+ weight : ,
327+ port : ,
328+ txt_values : ,
329+ ip : ,
330+ ) )
333331}
0 commit comments