Solve the given resource for the given value.

        The solving is done by the first resource solver class that returns ``True`` when calling
        its ``can_solve`` method for the given resource, and that doesn't raise a ``CannotSolve``
         exception.

        Arguments
        ---------
        value : ?
            A value to be solved with the given resource.
        resource : dataql.resources.Resource
            An instance of a subclass of ``Resource`` to be solved with the given value.

        Returns
        -------
        The solved result.

        Raises
        ------
        dataql.solvers.exceptions.SolveFailure
            If no solvers were able to solve the resource. This happen if a solver says that
            it can solve a resource (by returning ``True`` when calling its ``can_solve`` method,
            but raises a ``CannotSolve`` exception during solving).

        Example
        -------

        >>> from datetime import date
        >>> registry = Registry()
        >>> registry.register(date, ['day', 'month', 'year', 'strftime'])
        >>> from dataql.resources import Field, Filter, List, Object, PosArg, SliceFilter
        >>> registry.solve_resource(date(2015, 6, 1), Field('day'))
        1

        # Create an object from which we'll want an object (``date``) and a list (``dates``)
        >>> obj = EntryPoints(registry,
        ...     date = date(2015, 6, 1),
        ...     dates = [date(2015, 6, 1), date(2015, 6, 2), date(2015, 6, 3)],
        ... )

        >>> from pprint import pprint  # will sort the dicts by keys
        >>> pprint(registry.solve_resource(
        ...     obj,
        ...     # Omit single filter as it's auto-created with the name of the resource.
        ...     Object('date', resources=[Field('day'), Field('month'), Field('year')])
        ... ))
        {'day': 1, 'month': 6, 'year': 2015}

        >>> registry.solve_resource(
        ...     obj,
        ...     # Omit single filter as it's auto-created with the name of the resource.
        ...     List('dates', resources=[Field('day'), Field('month'), Field('year')])
        ... )
        [[1, 6, 2015], [2, 6, 2015], [3, 6, 2015]]

        >>> registry.solve_resource(
        ...     obj,
        ...     Field('dates', filters=[Filter('dates'), SliceFilter(1)])
        ... )
        '2015-06-02'

        # List of fields
        >>> registry.solve_resource(
        ...     obj,
        ...     List('dates',
        ...         filters=[Filter('dates'), SliceFilter(slice(1, None, None))],
        ...         resources=[Field('date', filters=[Filter('strftime', args=[PosArg('%F')])])]
        ...     )
        ... )
        ['2015-06-02', '2015-06-03']

        # List of objects
        >>> registry.solve_resource(
        ...     obj,
        ...     List('dates',
        ...         filters=[Filter('dates'), SliceFilter(slice(1, None, None))],
        ...         resources=[Object(None, resources=[
        ...             Field('date', filters=[Filter('strftime', args=[PosArg('%F')])])
        ...         ]
        ...     )]
        ... ))
        [{'date': '2015-06-02'}, {'date': '2015-06-03'}]

        # List of list
        >>> pprint(registry.solve_resource(
        ...     obj,
        ...     List(None,
        ...         filters=[Filter('dates'), SliceFilter(slice(None, None, 2))],
        ...         resources=[
        ...             Field(None, [Filter('strftime', args=[PosArg('%F')])]),
        ...             Object(None, resources=[Field('day'), Field('month'), Field('year')]),
        ...             ]
        ...     )
        ... ))
        [['2015-06-01', {'day': 1, 'month': 6, 'year': 2015}],
         ['2015-06-03', {'day': 3, 'month': 6, 'year': 2015}]]

        # Test the dict-like approach
        >>> class MyDict(dict):
        ...     foo = 1
        ...     bar = 2
        >>> registry.register(MyDict, ['foo', 'baz'])
        >>> d = MyDict(baz=3, qux=4)
        >>> registry.solve_resource(d, Field('foo'))
        1
        >>> registry.solve_resource(d, Field('bar'))  # doctest: +ELLIPSIS
        Traceback (most recent call last):
        dataql...AttributeNotFound: `bar` is not an allowed attribute for `...MyDict`
        >>> registry.solve_resource(d, Field('baz'))
        3
        >>> registry.solve_resource(d, Field('qux'))  # doctest: +ELLIPSIS
        Traceback (most recent call last):
        dataql...AttributeNotFound: `qux` is not an allowed attribute for `...MyDict`


        # Example of ``SolveFailure`` exception.
        >>> from dataql.solvers.exceptions import CannotSolve
        >>> raise SolveFailure(registry, Field('fromtimestamp'), date)
        Traceback (most recent call last):
        dataql.solvers.exceptions.SolveFailure: Unable to solve `<Field[fromtimestamp]>`.

def solve_resource(self, value, resource):
        """Solve the given resource for the given value.

        The solving is done by the first resource solver class that returns ``True`` when calling
        its ``can_solve`` method for the given resource, and that doesn't raise a ``CannotSolve``
         exception.

        Arguments
        ---------
        value : ?
            A value to be solved with the given resource.
        resource : dataql.resources.Resource
            An instance of a subclass of ``Resource`` to be solved with the given value.

        Returns
        -------
        The solved result.

        Raises
        ------
        dataql.solvers.exceptions.SolveFailure
            If no solvers were able to solve the resource. This happen if a solver says that
            it can solve a resource (by returning ``True`` when calling its ``can_solve`` method,
            but raises a ``CannotSolve`` exception during solving).

        Example
        -------

        >>> from datetime import date
        >>> registry = Registry()
        >>> registry.register(date, ['day', 'month', 'year', 'strftime'])
        >>> from dataql.resources import Field, Filter, List, Object, PosArg, SliceFilter
        >>> registry.solve_resource(date(2015, 6, 1), Field('day'))
        1

        # Create an object from which we'll want an object (``date``) and a list (``dates``)
        >>> obj = EntryPoints(registry,
        ...     date = date(2015, 6, 1),
        ...     dates = [date(2015, 6, 1), date(2015, 6, 2), date(2015, 6, 3)],
        ... )

        >>> from pprint import pprint  # will sort the dicts by keys
        >>> pprint(registry.solve_resource(
        ...     obj,
        ...     # Omit single filter as it's auto-created with the name of the resource.
        ...     Object('date', resources=[Field('day'), Field('month'), Field('year')])
        ... ))
        {'day': 1, 'month': 6, 'year': 2015}

        >>> registry.solve_resource(
        ...     obj,
        ...     # Omit single filter as it's auto-created with the name of the resource.
        ...     List('dates', resources=[Field('day'), Field('month'), Field('year')])
        ... )
        [[1, 6, 2015], [2, 6, 2015], [3, 6, 2015]]

        >>> registry.solve_resource(
        ...     obj,
        ...     Field('dates', filters=[Filter('dates'), SliceFilter(1)])
        ... )
        '2015-06-02'

        # List of fields
        >>> registry.solve_resource(
        ...     obj,
        ...     List('dates',
        ...         filters=[Filter('dates'), SliceFilter(slice(1, None, None))],
        ...         resources=[Field('date', filters=[Filter('strftime', args=[PosArg('%F')])])]
        ...     )
        ... )
        ['2015-06-02', '2015-06-03']

        # List of objects
        >>> registry.solve_resource(
        ...     obj,
        ...     List('dates',
        ...         filters=[Filter('dates'), SliceFilter(slice(1, None, None))],
        ...         resources=[Object(None, resources=[
        ...             Field('date', filters=[Filter('strftime', args=[PosArg('%F')])])
        ...         ]
        ...     )]
        ... ))
        [{'date': '2015-06-02'}, {'date': '2015-06-03'}]

        # List of list
        >>> pprint(registry.solve_resource(
        ...     obj,
        ...     List(None,
        ...         filters=[Filter('dates'), SliceFilter(slice(None, None, 2))],
        ...         resources=[
        ...             Field(None, [Filter('strftime', args=[PosArg('%F')])]),
        ...             Object(None, resources=[Field('day'), Field('month'), Field('year')]),
        ...             ]
        ...     )
        ... ))
        [['2015-06-01', {'day': 1, 'month': 6, 'year': 2015}],
         ['2015-06-03', {'day': 3, 'month': 6, 'year': 2015}]]

        # Test the dict-like approach
        >>> class MyDict(dict):
        ...     foo = 1
        ...     bar = 2
        >>> registry.register(MyDict, ['foo', 'baz'])
        >>> d = MyDict(baz=3, qux=4)
        >>> registry.solve_resource(d, Field('foo'))
        1
        >>> registry.solve_resource(d, Field('bar'))  # doctest: +ELLIPSIS
        Traceback (most recent call last):
        dataql...AttributeNotFound: `bar` is not an allowed attribute for `...MyDict`
        >>> registry.solve_resource(d, Field('baz'))
        3
        >>> registry.solve_resource(d, Field('qux'))  # doctest: +ELLIPSIS
        Traceback (most recent call last):
        dataql...AttributeNotFound: `qux` is not an allowed attribute for `...MyDict`


        # Example of ``SolveFailure`` exception.
        >>> from dataql.solvers.exceptions import CannotSolve
        >>> raise SolveFailure(registry, Field('fromtimestamp'), date)
        Traceback (most recent call last):
        dataql.solvers.exceptions.SolveFailure: Unable to solve `<Field[fromtimestamp]>`.

        """

        for solver in self.get_resource_solvers(resource):
            try:
                return solver.solve(value, resource)
            except CannotSolve:
                continue

        raise SolveFailure(self, resource, value)