forked from FlixCoder/fhir-sdk
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copied recent changes over to R4B and STU3
- Loading branch information
1 parent
00f0eda
commit d649ec8
Showing
13 changed files
with
475 additions
and
259 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,77 @@ | ||
//! Client search implementation. | ||
use crate::client::search::NextPageCursor; | ||
use crate::client::{search::SearchExecutor, Client, Error, FhirR4B, SearchParameters}; | ||
use fhir_model::r4b::resources::{DomainResource, NamedResource, Resource}; | ||
use futures::Stream; | ||
use paging::Paged; | ||
use async_trait::async_trait; | ||
use fhir_model::r4b::resources::{Bundle, DomainResource, NamedResource, Resource}; | ||
use paging::{Page, Unpaged}; | ||
|
||
#[allow(unused_imports)] | ||
pub use params::*; | ||
use reqwest::Url; | ||
use tracing::warn; | ||
|
||
mod paging; | ||
mod params; | ||
|
||
#[async_trait] | ||
impl<R> SearchExecutor<R> for Client<FhirR4B> | ||
where | ||
R: NamedResource + DomainResource + TryFrom<Resource> + 'static, | ||
{ | ||
fn execute_search( | ||
#[allow(refining_impl_trait)] | ||
async fn search_paged( | ||
self, | ||
params: SearchParameters, | ||
) -> impl Stream<Item = Result<R, Error>> + Send + 'static { | ||
page_size: Option<u32>, | ||
) -> Result<(Page<R>, Option<NextPageCursor<Self, R>>), Error> { | ||
let mut url = self.url(&[R::TYPE.as_str()]); | ||
url.query_pairs_mut().extend_pairs(params.into_queries()).finish(); | ||
|
||
Paged::new(self, url) | ||
if let Some(page_size) = page_size { | ||
url.query_pairs_mut().append_pair("_count", &page_size.to_string()); | ||
} | ||
|
||
self.fetch_next_page(url).await | ||
} | ||
|
||
#[allow(refining_impl_trait)] | ||
async fn fetch_next_page( | ||
self, | ||
url: Url, | ||
) -> Result<(Page<R>, Option<NextPageCursor<Self, R>>), Error> { | ||
let searchset: Bundle = self.fetch_resource(url).await?; | ||
|
||
let cursor = match find_next_page_url(&searchset) { | ||
Some(Ok(u)) => Some(NextPageCursor::new(self.clone(), u)), | ||
Some(Err(e)) => { | ||
warn!("Unable to parse next page URL: {e}"); | ||
|
||
None | ||
} | ||
_ => None, | ||
}; | ||
|
||
let page = Page::from_searchset(self, searchset); | ||
|
||
Ok((page, cursor)) | ||
} | ||
|
||
#[allow(refining_impl_trait)] | ||
async fn search_unpaged(self, params: SearchParameters) -> Result<Unpaged<R>, Error> { | ||
let mut url = self.url(&[R::TYPE.as_str()]); | ||
url.query_pairs_mut().extend_pairs(params.into_queries()).finish(); | ||
|
||
let searchset: Bundle = self.fetch_resource(url.clone()).await?; | ||
|
||
Ok(Unpaged::from_searchset(self, searchset)) | ||
} | ||
} | ||
|
||
/// Find the URL of the next page of the results returned in the Bundle. | ||
pub(self) fn find_next_page_url(bundle: &Bundle) -> Option<Result<Url, Error>> { | ||
let url_str = | ||
bundle.link.iter().flatten().find(|link| link.relation == "next").map(|link| &link.url)?; | ||
|
||
Some(Url::parse(url_str).map_err(|_| Error::UrlParse(url_str.to_string()))) | ||
} |
Oops, something went wrong.